class MenuWindow(QMainWindow): def __init__(self): super().__init__() self.href = '/top/' self.file_name = FILE_NAME + '.json' self.window2 = None self.create_main_window() def create_main_window(self): lbl1 = QLabel("Choose needed section", self) lbl1.setGeometry(40, 0, 200, 35) self.sections_combo = QComboBox(self) for ref in _SECTIONS_REF: self.sections_combo.addItem(ref) self.sections_combo.setGeometry(40, 35, 200, 35) lbl2 = QLabel("Choose needed format", self) lbl2.setGeometry(40, 70, 200, 35) self.format_combo = QComboBox(self) for form in _FORMAT: self.format_combo.addItem(form) self.format_combo.setGeometry(40, 105, 200, 35) self.sections_combo.activated[str].connect(self.sections_combo_Activated) self.sections_combo.setCurrentIndex(int(self.sections_combo.findText('За сутки'))) self.format_combo.activated[str].connect(self.format_combo_Activated) self.format_combo.setCurrentIndex(int(self.format_combo.findText('JSON'))) btn1 = QPushButton("GO", self) btn1.setGeometry(40, 140, 200, 35) btn1.clicked.connect(self.buttonClicked) self.setGeometry(300, 300, 300, 200) self.setWindowTitle('Main') self.show() def buttonClicked(self): pars = Parser() if self.window2 is None: self.window2 = OutputWindow(str(pars.parse_site(self.href, self.file_name))) self.window2.show() self.close() def sections_combo_Activated(self, text): self.href = _SECTIONS_REF.get(text) def format_combo_Activated(self, text): self.file_name = FILE_NAME + _FORMAT.get(text)
def add_row(self,i,thick,material,dos_layer,pl_file,name): self.tab.blockSignals(True) dos_file="" if dos_layer.startswith("dos")==True: dos_file="active layer" else: dos_file=dos_layer item1 = QTableWidgetItem(str(name)) self.tab.setItem(i,0,item1) item2 = QTableWidgetItem(str(thick)) self.tab.setItem(i,1,item2) combobox = QComboBox() #combobox.setEditable(True) for a in self.material_files: combobox.addItem(str(a)) self.tab.setCellWidget(i,2, combobox) combobox.setCurrentIndex(combobox.findText(material)) p=combobox.palette() p.setColor(QPalette.Active, QPalette.Button, Qt.white); p.setColor(QPalette.Inactive, QPalette.Button, Qt.white); combobox.setPalette(p) #item3 = QTableWidgetItem(str(dos_file)) #self.tab.setItem(i,3,item3) combobox_layer_type = QComboBox() #combobox.setEditable(True) combobox_layer_type.addItem("contact") combobox_layer_type.addItem("active layer") combobox_layer_type.addItem("other") self.tab.setCellWidget(i,3, combobox_layer_type) combobox_layer_type.setCurrentIndex(combobox_layer_type.findText(str(dos_file).lower())) item3 = QTableWidgetItem(str(dos_layer)) self.tab.setItem(i,4,item3) item3 = QTableWidgetItem(str(pl_file)) self.tab.setItem(i,5,item3) scan_item_add("epitaxy.inp","#layer_material_file"+str(i),_("Material for ")+name,2) scan_item_add("epitaxy.inp","#layer_width"+str(i),_("Layer width ")+name,1) combobox.currentIndexChanged.connect(self.combo_changed) combobox_layer_type.currentIndexChanged.connect(self.layer_type_edit) self.tab.blockSignals(False)
class HydroprintGUI(myqt.DialogWindow): ConsoleSignal = QSignal(str) def __init__(self, datamanager, parent=None): super(HydroprintGUI, self).__init__(parent, maximize=True) self.__updateUI = True # Child widgets: self.dmngr = datamanager self.dmngr.wldsetChanged.connect(self.wldset_changed) self.dmngr.wxdsetChanged.connect(self.wxdset_changed) self.page_setup_win = PageSetupWin(self) self.page_setup_win.newPageSetupSent.connect(self.layout_changed) self.color_palette_win = ColorsSetupWin(self) self.color_palette_win.newColorSetupSent.connect(self.update_colors) # Memory path variable: self.save_fig_dir = self.workdir # Generate UI: self.__initUI__() def __initUI__(self): # ---- Toolbar self.btn_save = btn_save = QToolButtonNormal(icons.get_icon('save')) btn_save.setToolTip('Save the well hydrograph') # btn_draw is usefull for debugging purposes btn_draw = QToolButtonNormal(icons.get_icon('refresh')) btn_draw.setToolTip('Force a refresh of the well hydrograph') btn_draw.hide() self.btn_load_layout = QToolButtonNormal( icons.get_icon('load_graph_config')) self.btn_load_layout.setToolTip( "<p>Load graph layout for the current water level " " datafile if it exists</p>") self.btn_load_layout.clicked.connect(self.load_layout_isClicked) self.btn_save_layout = QToolButtonNormal( icons.get_icon('save_graph_config')) self.btn_save_layout.setToolTip('Save current graph layout') self.btn_save_layout.clicked.connect(self.save_layout_isClicked) btn_bestfit_waterlvl = QToolButtonNormal(icons.get_icon('fit_y')) btn_bestfit_waterlvl.setToolTip('Best fit the water level scale') btn_bestfit_time = QToolButtonNormal(icons.get_icon('fit_x')) btn_bestfit_time.setToolTip('Best fit the time scale') self.btn_page_setup = QToolButtonNormal(icons.get_icon('page_setup')) self.btn_page_setup.setToolTip('Show the page setup window') self.btn_page_setup.clicked.connect(self.page_setup_win.show) btn_color_pick = QToolButtonNormal(icons.get_icon('color_picker')) btn_color_pick.setToolTip('<p>Show a window to setup the color palette' ' used to draw the hydrograph</p.') btn_color_pick.clicked.connect(self.color_palette_win.show) self.btn_language = LangToolButton() self.btn_language.setToolTip( "Set the language of the text shown in the graph.") self.btn_language.sig_lang_changed.connect(self.layout_changed) self.btn_language.setIconSize(icons.get_iconsize('normal')) # ---- Zoom Panel btn_zoom_out = QToolButtonSmall(icons.get_icon('zoom_out')) btn_zoom_out.setToolTip('Zoom out (ctrl + mouse-wheel-down)') btn_zoom_out.clicked.connect(self.zoom_out) btn_zoom_in = QToolButtonSmall(icons.get_icon('zoom_in')) btn_zoom_in.setToolTip('Zoom in (ctrl + mouse-wheel-up)') btn_zoom_in.clicked.connect(self.zoom_in) self.zoom_disp = QSpinBox() self.zoom_disp.setAlignment(Qt.AlignCenter) self.zoom_disp.setButtonSymbols(QAbstractSpinBox.NoButtons) self.zoom_disp.setReadOnly(True) self.zoom_disp.setSuffix(' %') self.zoom_disp.setRange(0, 9999) self.zoom_disp.setValue(100) zoom_pan = myqt.QFrameLayout() zoom_pan.setSpacing(3) zoom_pan.addWidget(btn_zoom_out, 0, 0) zoom_pan.addWidget(btn_zoom_in, 0, 1) zoom_pan.addWidget(self.zoom_disp, 0, 2) # LAYOUT : btn_list = [btn_save, btn_draw, self.btn_load_layout, self.btn_save_layout, VSep(), btn_bestfit_waterlvl, btn_bestfit_time, VSep(), self.btn_page_setup, btn_color_pick, self.btn_language, VSep(), zoom_pan] subgrid_toolbar = QGridLayout() toolbar_widget = QWidget() row = 0 for col, btn in enumerate(btn_list): subgrid_toolbar.addWidget(btn, row, col) subgrid_toolbar.setSpacing(5) subgrid_toolbar.setContentsMargins(0, 0, 0, 0) subgrid_toolbar.setColumnStretch(col + 1, 100) toolbar_widget.setLayout(subgrid_toolbar) # ---- LEFT PANEL # SubGrid Hydrograph Frame : self.hydrograph = hydrograph.Hydrograph() self.hydrograph_scrollarea = mplFigViewer.ImageViewer() self.hydrograph_scrollarea.zoomChanged.connect(self.zoom_disp.setValue) grid_hydrograph = QGridLayout() grid_hydrograph.addWidget(self.hydrograph_scrollarea, 0, 0) grid_hydrograph.setRowStretch(0, 500) grid_hydrograph.setColumnStretch(0, 500) grid_hydrograph.setContentsMargins(0, 0, 0, 0) # (L, T, R, B) # ASSEMBLING SubGrids : grid_layout = QGridLayout() self.grid_layout_widget = QFrame() row = 0 grid_layout.addWidget(toolbar_widget, row, 0) row += 1 grid_layout.addLayout(grid_hydrograph, row, 0) grid_layout.setContentsMargins(0, 0, 0, 0) # (L, T, R, B) grid_layout.setSpacing(5) grid_layout.setColumnStretch(0, 500) grid_layout.setRowStretch(1, 500) self.grid_layout_widget.setLayout(grid_layout) # ---- Right Panel self.tabscales = self.__init_scalesTabWidget__() self.right_panel = myqt.QFrameLayout() self.right_panel.addWidget(self.dmngr, 0, 0) self.right_panel.addWidget(self.tabscales, 1, 0) self.right_panel.setRowStretch(2, 100) self.right_panel.setSpacing(15) # ---- MAIN GRID mainGrid = QGridLayout() mainGrid.addWidget(self.grid_layout_widget, 0, 0) mainGrid.addWidget(VSep(), 0, 1) mainGrid.addWidget(self.right_panel, 0, 2) mainGrid.setContentsMargins(10, 10, 10, 10) # (L, T, R, B) mainGrid.setSpacing(15) mainGrid.setColumnStretch(0, 500) mainGrid.setColumnMinimumWidth(2, 250) self.setLayout(mainGrid) # ---- EVENTS # Toolbox Layout : btn_bestfit_waterlvl.clicked.connect(self.best_fit_waterlvl) btn_bestfit_time.clicked.connect(self.best_fit_time) btn_draw.clicked.connect(self.draw_hydrograph) btn_save.clicked.connect(self.select_save_path) # Hydrograph Layout : self.Ptot_scale.valueChanged.connect(self.layout_changed) self.qweather_bin.currentIndexChanged.connect(self.layout_changed) # ---- Init Image self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def __init_scalesTabWidget__(self): class QRowLayout(QGridLayout): def __init__(self, items, parent=None): super(QRowLayout, self).__init__(parent) for col, item in enumerate(items): self.addWidget(item, 0, col) self.setContentsMargins(0, 0, 0, 0) self.setColumnStretch(0, 100) # ---- Time axis properties # Generate the widgets : self.date_start_widget = QDateEdit() self.date_start_widget.setDisplayFormat('01 / MM / yyyy') self.date_start_widget.setAlignment(Qt.AlignCenter) self.date_start_widget.dateChanged.connect(self.layout_changed) self.date_end_widget = QDateEdit() self.date_end_widget.setDisplayFormat('01 / MM / yyyy') self.date_end_widget.setAlignment(Qt.AlignCenter) self.date_end_widget.dateChanged.connect(self.layout_changed) self.time_scale_label = QComboBox() self.time_scale_label.setEditable(False) self.time_scale_label.setInsertPolicy(QComboBox.NoInsert) self.time_scale_label.addItems(['Month', 'Year']) self.time_scale_label.setCurrentIndex(0) self.time_scale_label.currentIndexChanged.connect(self.layout_changed) self.dateDispFreq_spinBox = QSpinBox() self.dateDispFreq_spinBox.setSingleStep(1) self.dateDispFreq_spinBox.setMinimum(1) self.dateDispFreq_spinBox.setMaximum(100) self.dateDispFreq_spinBox.setValue( self.hydrograph.date_labels_pattern) self.dateDispFreq_spinBox.setAlignment(Qt.AlignCenter) self.dateDispFreq_spinBox.setKeyboardTracking(False) self.dateDispFreq_spinBox.valueChanged.connect(self.layout_changed) # Setting up the layout : widget_time_scale = QFrame() widget_time_scale.setFrameStyle(0) grid_time_scale = QGridLayout() GRID = [[QLabel('From :'), self.date_start_widget], [QLabel('To :'), self.date_end_widget], [QLabel('Scale :'), self.time_scale_label], [QLabel('Date Disp. Pattern:'), self.dateDispFreq_spinBox]] for i, ROW in enumerate(GRID): grid_time_scale.addLayout(QRowLayout(ROW), i, 1) grid_time_scale.setVerticalSpacing(5) grid_time_scale.setContentsMargins(10, 10, 10, 10) widget_time_scale.setLayout(grid_time_scale) # ----- Water level axis properties # Widget : self.waterlvl_scale = QDoubleSpinBox() self.waterlvl_scale.setSingleStep(0.05) self.waterlvl_scale.setMinimum(0.05) self.waterlvl_scale.setSuffix(' m') self.waterlvl_scale.setAlignment(Qt.AlignCenter) self.waterlvl_scale.setKeyboardTracking(False) self.waterlvl_scale.valueChanged.connect(self.layout_changed) self.waterlvl_scale.setFixedWidth(100) self.waterlvl_max = QDoubleSpinBox() self.waterlvl_max.setSingleStep(0.1) self.waterlvl_max.setSuffix(' m') self.waterlvl_max.setAlignment(Qt.AlignCenter) self.waterlvl_max.setMinimum(-1000) self.waterlvl_max.setMaximum(1000) self.waterlvl_max.setKeyboardTracking(False) self.waterlvl_max.valueChanged.connect(self.layout_changed) self.waterlvl_max.setFixedWidth(100) self.NZGridWL_spinBox = QSpinBox() self.NZGridWL_spinBox.setSingleStep(1) self.NZGridWL_spinBox.setMinimum(1) self.NZGridWL_spinBox.setMaximum(50) self.NZGridWL_spinBox.setValue(self.hydrograph.NZGrid) self.NZGridWL_spinBox.setAlignment(Qt.AlignCenter) self.NZGridWL_spinBox.setKeyboardTracking(False) self.NZGridWL_spinBox.valueChanged.connect(self.layout_changed) self.NZGridWL_spinBox.setFixedWidth(100) self.datum_widget = QComboBox() self.datum_widget.addItems(['Ground Surface', 'Sea Level']) self.datum_widget.currentIndexChanged.connect(self.layout_changed) # Layout : subgrid_WLScale = QGridLayout() GRID = [[QLabel('Minimum :'), self.waterlvl_max], [QLabel('Scale :'), self.waterlvl_scale], [QLabel('Grid Divisions :'), self.NZGridWL_spinBox], [QLabel('Datum :'), self.datum_widget]] for i, ROW in enumerate(GRID): subgrid_WLScale.addLayout(QRowLayout(ROW), i, 1) subgrid_WLScale.setVerticalSpacing(5) subgrid_WLScale.setContentsMargins(10, 10, 10, 10) # (L, T, R, B) WLScale_widget = QFrame() WLScale_widget.setFrameStyle(0) WLScale_widget.setLayout(subgrid_WLScale) # ---- Weather Axis # Widgets : self.Ptot_scale = QSpinBox() self.Ptot_scale.setSingleStep(5) self.Ptot_scale.setMinimum(5) self.Ptot_scale.setMaximum(500) self.Ptot_scale.setValue(20) self.Ptot_scale.setSuffix(' mm') self.Ptot_scale.setAlignment(Qt.AlignCenter) self.qweather_bin = QComboBox() self.qweather_bin.setEditable(False) self.qweather_bin.setInsertPolicy(QComboBox.NoInsert) self.qweather_bin.addItems(['day', 'week', 'month']) self.qweather_bin.setCurrentIndex(1) # Layout : layout = QGridLayout() GRID = [[QLabel('Precip. Scale :'), self.Ptot_scale], [QLabel('Resampling :'), self.qweather_bin]] for i, row in enumerate(GRID): layout.addLayout(QRowLayout(row), i, 1) layout.setVerticalSpacing(5) layout.setContentsMargins(10, 10, 10, 10) # (L,T,R,B) layout.setRowStretch(i+1, 100) widget_weather_scale = QFrame() widget_weather_scale.setFrameStyle(0) widget_weather_scale.setLayout(layout) # ---- ASSEMBLING TABS tabscales = QTabWidget() tabscales.addTab(widget_time_scale, 'Time') tabscales.addTab(WLScale_widget, 'Water Level') tabscales.addTab(widget_weather_scale, 'Weather') return tabscales @property def workdir(self): return self.dmngr.workdir # ---- Utilities def zoom_in(self): self.hydrograph_scrollarea.zoomIn() def zoom_out(self): self.hydrograph_scrollarea.zoomOut() def update_colors(self): self.hydrograph.update_colors() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) # ---- Datasets Handlers @property def wldset(self): return self.dmngr.get_current_wldset() @property def wxdset(self): return self.dmngr.get_current_wxdset() def wldset_changed(self): """Handle when the water level dataset of the datamanager changes.""" if self.wldset is None: self.clear_hydrograph() return else: self.hydrograph.set_wldset(self.wldset) self.hydrograph.gluedf = self.wldset.get_glue_at(-1) # Load the manual measurements. fname = os.path.join( self.workdir, "Water Levels", 'waterlvl_manual_measurements') tmeas, wlmeas = load_waterlvl_measures(fname, self.wldset['Well']) self.wldset.set_wlmeas(tmeas, wlmeas) # Setup the layout of the hydrograph. layout = self.wldset.get_layout() if layout is not None: msg = ("Loading existing graph layout for well %s." % self.wldset['Well']) print(msg) self.ConsoleSignal.emit('<font color=black>%s</font>' % msg) self.load_graph_layout(layout) else: print('No graph layout exists for well %s.' % self.wldset['Well']) # Fit Water Level in Layout : self.__updateUI = False self.best_fit_waterlvl() self.best_fit_time() if self.dmngr.set_closest_wxdset() is None: self.draw_hydrograph() self.__updateUI = True def wxdset_changed(self): """Handle when the weather dataset of the datamanager changes.""" if self.wldset is None: self.clear_hydrograph() else: self.hydrograph.set_wxdset(self.wxdset) QCoreApplication.processEvents() self.draw_hydrograph() # ---- Draw Hydrograph Handlers def best_fit_waterlvl(self): wldset = self.dmngr.get_current_wldset() if wldset is not None: WLscale, WLmin = self.hydrograph.best_fit_waterlvl() self.waterlvl_scale.setValue(WLscale) self.waterlvl_max.setValue(WLmin) def best_fit_time(self): wldset = self.dmngr.get_current_wldset() if wldset is not None: date0, date1 = self.hydrograph.best_fit_time(wldset.xldates) self.date_start_widget.setDate(QDate(date0[0], date0[1], date0[2])) self.date_end_widget.setDate(QDate(date1[0], date1[1], date1[2])) @QSlot() def mrc_wl_changed(self): """ Force a redraw of the MRC water levels after the results have changed for the dataset. """ self.hydrograph.draw_mrc_wl() self.hydrograph.setup_legend() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) @QSlot(GLUEDataFrameBase) def glue_wl_changed(self, gluedf): """ Force a redraw of the GLUE water levels after the results have changed for the dataset. """ self.hydrograph.set_gluedf(gluedf) self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def layout_changed(self): """ When an element of the graph layout is changed in the UI. """ if self.__updateUI is False: return self.update_graph_layout_parameter() if self.hydrograph.isHydrographExists is False: return sender = self.sender() if sender == self.btn_language: self.hydrograph.draw_ylabels() self.hydrograph.setup_xticklabels() self.hydrograph.setup_legend() elif sender in [self.waterlvl_max, self.waterlvl_scale]: self.hydrograph.setup_waterlvl_scale() self.hydrograph.draw_ylabels() elif sender == self.NZGridWL_spinBox: self.hydrograph.setup_waterlvl_scale() self.hydrograph.update_precip_scale() self.hydrograph.draw_ylabels() elif sender == self.Ptot_scale: self.hydrograph.update_precip_scale() self.hydrograph.draw_ylabels() elif sender == self.datum_widget: yoffset = int(self.wldset['Elevation']/self.hydrograph.WLscale) yoffset *= self.hydrograph.WLscale self.hydrograph.WLmin = (yoffset - self.hydrograph.WLmin) self.waterlvl_max.blockSignals(True) self.waterlvl_max.setValue(self.hydrograph.WLmin) self.waterlvl_max.blockSignals(False) # This is calculated so that trailing zeros in the altitude of the # well is not carried to the y axis labels, so that they remain a # int multiple of *WLscale*. self.hydrograph.setup_waterlvl_scale() self.hydrograph.draw_waterlvl() self.hydrograph.draw_ylabels() elif sender in [self.date_start_widget, self.date_end_widget]: self.hydrograph.set_time_scale() self.hydrograph.draw_weather() self.hydrograph.draw_figure_title() elif sender == self.dateDispFreq_spinBox: self.hydrograph.set_time_scale() self.hydrograph.setup_xticklabels() elif sender == self.page_setup_win: self.hydrograph.update_fig_size() # Implicitly call : set_margins() # draw_ylabels() # set_time_scale() # draw_figure_title self.hydrograph.draw_waterlvl() self.hydrograph.setup_legend() elif sender == self.qweather_bin: self.hydrograph.resample_bin() self.hydrograph.draw_weather() self.hydrograph.draw_ylabels() elif sender == self.time_scale_label: self.hydrograph.set_time_scale() self.hydrograph.draw_weather() else: print('No action for this widget yet.') # !!!! temporary fix until I can find a better solution !!!! # sender.blockSignals(True) if type(sender) in [QDoubleSpinBox, QSpinBox]: sender.setReadOnly(True) for i in range(10): QCoreApplication.processEvents() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) for i in range(10): QCoreApplication.processEvents() if type(sender) in [QDoubleSpinBox, QSpinBox]: sender.setReadOnly(False) # sender.blockSignals(False) def update_graph_layout_parameter(self): # language : self.hydrograph.language = self.btn_language.language # Scales : self.hydrograph.WLmin = self.waterlvl_max.value() self.hydrograph.WLscale = self.waterlvl_scale.value() self.hydrograph.RAINscale = self.Ptot_scale.value() self.hydrograph.NZGrid = self.NZGridWL_spinBox.value() # WL Datum : self.hydrograph.WLdatum = self.datum_widget.currentIndex() # Dates : self.hydrograph.datemode = self.time_scale_label.currentText() year = self.date_start_widget.date().year() month = self.date_start_widget.date().month() self.hydrograph.TIMEmin = xldate_from_date_tuple((year, month, 1), 0) year = self.date_end_widget.date().year() month = self.date_end_widget.date().month() self.hydrograph.TIMEmax = xldate_from_date_tuple((year, month, 1), 0) self.hydrograph.date_labels_pattern = self.dateDispFreq_spinBox.value() # Page Setup : self.hydrograph.fwidth = self.page_setup_win.pageSize[0] self.hydrograph.fheight = self.page_setup_win.pageSize[1] self.hydrograph.va_ratio = self.page_setup_win.va_ratio self.hydrograph.trend_line = self.page_setup_win.isTrendLine self.hydrograph.isLegend = self.page_setup_win.isLegend self.hydrograph.isGraphTitle = self.page_setup_win.isGraphTitle self.hydrograph.set_meteo_on(self.page_setup_win.is_meteo_on) self.hydrograph.set_glue_wl_on(self.page_setup_win.is_glue_wl_on) self.hydrograph.set_mrc_wl_on(self.page_setup_win.is_mrc_wl_on) self.hydrograph.set_figframe_lw(self.page_setup_win.figframe_lw) # Weather bins : self.hydrograph.bwidth_indx = self.qweather_bin.currentIndex() def clear_hydrograph(self): """Clear the hydrograph figure to show only a blank canvas.""" self.hydrograph.clf() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def draw_hydrograph(self): if self.dmngr.wldataset_count() == 0: msg = 'Please import a valid water level data file first.' self.ConsoleSignal.emit('<font color=red>%s</font>' % msg) self.emit_warning(msg) return self.update_graph_layout_parameter() # Generate and Display Graph : for i in range(5): QCoreApplication.processEvents() QApplication.setOverrideCursor(Qt.WaitCursor) self.hydrograph.set_wldset(self.dmngr.get_current_wldset()) self.hydrograph.set_wxdset(self.dmngr.get_current_wxdset()) self.hydrograph.generate_hydrograph() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) QApplication.restoreOverrideCursor() def select_save_path(self): """ Open a dialog where the user can select a file name to save the hydrograph. """ if self.wldset is None: return ffmat = "*.pdf;;*.svg;;*.png" fname = find_unique_filename(osp.join( self.save_fig_dir, 'hydrograph_%s.pdf' % self.wldset['Well'])) fname, ftype = QFileDialog.getSaveFileName( self, "Save Figure", fname, ffmat) if fname: ftype = ftype.replace('*', '') fname = fname if fname.endswith(ftype) else fname + ftype self.save_fig_dir = os.path.dirname(fname) try: self.save_figure(fname) except PermissionError: msg = "The file is in use by another application or user." QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) self.select_save_path() def save_figure(self, fname): """Save the hydrograph figure in a file.""" self.hydrograph.generate_hydrograph() self.hydrograph.savefig(fname) # ---- Graph Layout Handlers def load_layout_isClicked(self): """Handle when the button to load the graph layout is clicked.""" if self.wldset is None: self.emit_warning( "Please import a valid water level data file first.") return layout = self.wldset.get_layout() if layout is None: self.emit_warning( "No graph layout exists for well %s." % self.wldset['Well']) else: self.load_graph_layout(layout) def load_graph_layout(self, layout): """Load the graph layout into the GUI.""" self.__updateUI = False # Scales : date = layout['TIMEmin'] date = xldate_as_tuple(date, 0) self.date_start_widget.setDate(QDate(date[0], date[1], date[2])) date = layout['TIMEmax'] date = xldate_as_tuple(date, 0) self.date_end_widget.setDate(QDate(date[0], date[1], date[2])) self.dateDispFreq_spinBox.setValue(layout['date_labels_pattern']) self.waterlvl_scale.setValue(layout['WLscale']) self.waterlvl_max.setValue(layout['WLmin']) self.NZGridWL_spinBox.setValue(layout['NZGrid']) self.Ptot_scale.setValue(layout['RAINscale']) x = ['mbgs', 'masl'].index(layout['WLdatum']) self.datum_widget.setCurrentIndex(x) self.qweather_bin.setCurrentIndex(layout['bwidth_indx']) self.time_scale_label.setCurrentIndex( self.time_scale_label.findText(layout['datemode'])) # ---- Language and colors self.btn_language.set_language(layout['language']) self.color_palette_win.load_colors() # ---- Page Setup self.page_setup_win.pageSize = (layout['fwidth'], layout['fheight']) self.page_setup_win.va_ratio = layout['va_ratio'] self.page_setup_win.isLegend = layout['legend_on'] self.page_setup_win.isGraphTitle = layout['title_on'] self.page_setup_win.isTrendLine = layout['trend_line'] self.page_setup_win.is_meteo_on = layout['meteo_on'] self.page_setup_win.is_glue_wl_on = layout['glue_wl_on'] self.page_setup_win.is_mrc_wl_on = layout['mrc_wl_on'] self.page_setup_win.figframe_lw = layout['figframe_lw'] self.page_setup_win.legend_on.set_value(layout['legend_on']) self.page_setup_win.title_on.set_value(layout['title_on']) self.page_setup_win.wltrend_on.set_value(layout['trend_line']) self.page_setup_win.meteo_on.set_value(layout['meteo_on']) self.page_setup_win.glue_wl_on.set_value(layout['glue_wl_on']) self.page_setup_win.mrc_wl_on.set_value(layout['mrc_wl_on']) self.page_setup_win.fframe_lw_widg.setValue(layout['figframe_lw']) self.page_setup_win.fwidth.setValue(layout['fwidth']) self.page_setup_win.fheight.setValue(layout['fheight']) self.page_setup_win.va_ratio_spinBox.setValue(layout['va_ratio']) # Check if Weather Dataset : if layout['wxdset'] in self.dmngr.wxdsets: self.dmngr.set_current_wxdset(layout['wxdset']) else: if self.dmngr.set_closest_wxdset() is None: self.draw_hydrograph() self.__updateUI = True def save_layout_isClicked(self): wldset = self.wldset if wldset is None: self.emit_warning( "Please import a valid water level data file first.") return layout = wldset.get_layout() if layout is not None: msg = ('A graph layout already exists for well %s.Do you want to' ' you want to replace it?') % wldset['Well'] reply = QMessageBox.question(self, 'Save Graph Layout', msg, QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.save_graph_layout() elif reply == QMessageBox.No: msg = "Graph layout not saved for well %s." % wldset['Well'] self.ConsoleSignal.emit('<font color=black>%s' % msg) else: self.save_graph_layout() def save_graph_layout(self): """Save the graph layout in the project hdf5 file.""" print("Saving the graph layout for well %s..." % self.wldset['Well'], end=" ") layout = {'WLmin': self.waterlvl_max.value(), 'WLscale': self.waterlvl_scale.value(), 'RAINscale': self.Ptot_scale.value(), 'fwidth': self.page_setup_win.pageSize[0], 'fheight': self.page_setup_win.pageSize[1], 'va_ratio': self.page_setup_win.va_ratio, 'NZGrid': self.NZGridWL_spinBox.value(), 'bwidth_indx': self.qweather_bin.currentIndex(), 'date_labels_pattern': self.dateDispFreq_spinBox.value(), 'datemode': self.time_scale_label.currentText()} layout['wxdset'] = None if self.wxdset is None else self.wxdset.name year = self.date_start_widget.date().year() month = self.date_start_widget.date().month() layout['TIMEmin'] = xldate_from_date_tuple((year, month, 1), 0) year = self.date_end_widget.date().year() month = self.date_end_widget.date().month() layout['TIMEmax'] = xldate_from_date_tuple((year, month, 1), 0) if self.datum_widget.currentIndex() == 0: layout['WLdatum'] = 'mbgs' else: layout['WLdatum'] = 'masl' # ---- Page Setup layout['title_on'] = bool(self.page_setup_win.isGraphTitle) layout['legend_on'] = bool(self.page_setup_win.isLegend) layout['language'] = self.btn_language.language layout['trend_line'] = bool(self.page_setup_win.isTrendLine) layout['meteo_on'] = bool(self.page_setup_win.is_meteo_on) layout['glue_wl_on'] = bool(self.page_setup_win.is_glue_wl_on) layout['mrc_wl_on'] = bool(self.page_setup_win.is_mrc_wl_on) layout['figframe_lw'] = self.page_setup_win.figframe_lw # Save the colors : cdb = ColorsReader() cdb.load_colors_db() layout['colors'] = cdb.RGB # Save the layout : self.wldset.save_layout(layout) msg = 'Layout saved successfully for well %s.' % self.wldset['Well'] self.ConsoleSignal.emit('<font color=black>%s</font>' % msg) print("done")
def __init__(self, layer): super().__init__(layer) self.grid_layout.addWidget(QLabel('size:'), 3, 0) sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) #sld.setInvertedAppearance(True) sld.setFixedWidth(75) sld.setMinimum(0) sld.setMaximum(100) sld.setSingleStep(1) value = self.layer.size if isinstance(value, Iterable): if isinstance(value, list): value = np.asarray(value) value = value.mean() sld.setValue(int(value)) sld.valueChanged[int].connect(lambda value=sld: self.changeSize(value)) self.grid_layout.addWidget(sld, 3, 1) face_comboBox = QComboBox() colors = self.layer._colors for c in colors: face_comboBox.addItem(c) index = face_comboBox.findText(self.layer.face_color, Qt.MatchFixedString) if index >= 0: face_comboBox.setCurrentIndex(index) face_comboBox.activated[str].connect( lambda text=face_comboBox: self.changeFaceColor(text)) self.grid_layout.addWidget(QLabel('face_color:'), 4, 0) self.grid_layout.addWidget(face_comboBox, 4, 1) edge_comboBox = QComboBox() colors = self.layer._colors for c in colors: edge_comboBox.addItem(c) index = edge_comboBox.findText(self.layer.edge_color, Qt.MatchFixedString) if index >= 0: edge_comboBox.setCurrentIndex(index) edge_comboBox.activated[str].connect( lambda text=edge_comboBox: self.changeEdgeColor(text)) self.grid_layout.addWidget(QLabel('edge_color:'), 5, 0) self.grid_layout.addWidget(edge_comboBox, 5, 1) symbol_comboBox = QComboBox() symbols = self.layer._marker_types for s in symbols: symbol_comboBox.addItem(s) index = symbol_comboBox.findText(self.layer.symbol, Qt.MatchFixedString) if index >= 0: symbol_comboBox.setCurrentIndex(index) symbol_comboBox.activated[str].connect( lambda text=symbol_comboBox: self.changeSymbol(text)) self.grid_layout.addWidget(QLabel('symbol:'), 6, 0) self.grid_layout.addWidget(symbol_comboBox, 6, 1) self.setExpanded(False)
def _add_to_internal_dict(self, element, parent, num_row): QueueModel._add_to_internal_dict(self, element, parent, num_row) if element.tag == "item": # each row gets one combobox for the extension and one for the quality options format_combobox = QComboBox() # see ComboBoxDelegate.createEditor() quality_combobox = QComboBox() # see ComboBoxDelegate.createEditor() self.combo_boxes_format[element] = format_combobox self.combo_boxes_quality[element] = quality_combobox selected_extension = self.getSelectedExtension(element) selected_quality = self.getSelectedQuality(element, selected_extension) for format in element.findall("format"): format_combobox.addItem(format.get("extension")) for option in element.findall("format[@extension='%s']/option" % selected_extension): quality_combobox.addItem(option.get("quality")) format_combobox.setCurrentIndex(format_combobox.findText(selected_extension)) quality_combobox.setCurrentIndex(quality_combobox.findText(selected_quality)) # setup defaults for path and filename if "path" not in element.attrib: path = self.settings.value("DefaultDownloadFolder") element.attrib["path"] = path if "filename" not in element.attrib: filename = self.settings.value("DefaultFileName") # some of the template-filling will happen when an Item is moved to DownloadModel, as # quality and extension will most probably change until then mapping = dict(title=element.get("title"), url=element.get("url"), host=element.get("host")) element.attrib["filename"] = fill_filename_template(filename, mapping)
class EnumConfigControl(ConfigControl): def __init__(self, config_item): ConfigControl.__init__(self, config_item) self._init_ui() def _init_ui(self): lbl_enum = QLabel(self._config_item.tag()) lbl_enum.setFixedWidth(self.LABEL_WIDTH) self._cmbo_enum = QComboBox() self._cmbo_enum.addItems(self._config_item.enum_names) selected = self._config_item.value() index = self._cmbo_enum.findText(selected, QtCore.Qt.MatchFixedString) self._cmbo_enum.setCurrentIndex(index) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.addWidget(lbl_enum) hbox.addWidget(self._cmbo_enum) hbox.addStretch() self.setLayout(hbox) def update_from_config(self): selected = self._config_item.value() index = self._cmbo_enum.findText(selected, QtCore.Qt.MatchFixedString) index = max(0, index) self._cmbo_enum.setCurrentIndex(index) def save_to_config(self): value = self._cmbo_enum.currentText() self._config_item.set(value)
class Select(MeasurementParameter): def __init__(self, values, defaultindex=0): super(Select, self).__init__() # if command line interface if self.cli: self.value = values[defaultindex] return # else self.widget = QComboBox() self.widget.mp = self for v in values: if self.widget.findText(v) != -1: raise Exception('Duplicate item in Select()') self.widget.addItem(v) @property def value(self): return self.value_ if self.cli else self.widget.currentText() #TODO: should also check if element is in list if in CLI mode @value.setter def value(self, val): self.value_ = val if not self.cli: index = self.widget.findText(val) if index == -1: raise Exception('Item not part of list') else: self.widget.setCurrentIndex(index)
def __init__(self, layer): super().__init__(layer) comboBox = QComboBox() for cmap in self.layer.colormaps: comboBox.addItem(cmap) index = comboBox.findText('hot', Qt.MatchFixedString) if index >= 0: comboBox.setCurrentIndex(index) comboBox.activated[str].connect( lambda text=comboBox: self.changeColor(text)) self.grid_layout.addWidget(QLabel('colormap:'), 3, 0) self.grid_layout.addWidget(comboBox, 3, 1) interp_comboBox = QComboBox() for interp in self.layer._interpolation_names: interp_comboBox.addItem(interp) index = interp_comboBox.findText(self.layer.interpolation, Qt.MatchFixedString) if index >= 0: interp_comboBox.setCurrentIndex(index) interp_comboBox.activated[str].connect( lambda text=interp_comboBox: self.changeInterpolation(text)) self.grid_layout.addWidget(QLabel('interpolation:'), 4, 0) self.grid_layout.addWidget(interp_comboBox, 4, 1) self.setExpanded(False)
class LibraryTaskManager(QWidget): class Runner(QRunnable): def __init__(self, function, args): super().__init__() self.function = function self.args = args def run(self): self.function(*self.args) def __init__(self): super().__init__() self.thread_pool = QThreadPool() self.task_combo = QComboBox() self.task_combo.currentIndexChanged.connect(self.get_item_status) self.progress = QProgressBar() self.progress.setMaximum(100) self.timer = QTimer() q_size = QSize(16, 16) self.icon_in_progress = QIcon.fromTheme("media-playback-start") self.icon_completed = QIcon.fromTheme("media-playback-stop") self.task_combo.setIconSize(q_size) self.timer.timeout.connect(self.timeout) self.task_lookup = {} self._init_ui() def _init_ui(self): layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(QLabel("Task Executor")) layout.addWidget(self.task_combo) layout.addWidget(self.progress) self.setLayout(layout) def execute(self, function, args): runner = self.Runner(function, args) runner.setAutoDelete(True) self.thread_pool.start(runner) def execute_with_progress(self, function, args, task_ref): self.execute(function, args) self.task_lookup[task_ref[0]] = task_ref[1] self.task_combo.addItem(self.icon_in_progress, task_ref[0]) self.task_combo.setCurrentIndex(self.task_combo.findText(task_ref[0])) def get_item_status(self): self.timer.start(500) def timeout(self): task_name = self.task_combo.currentText() task_ref = self.task_lookup[task_name] print(f"status for {task_ref}") status = LibraryManagement.get_task_status(task_ref) self.progress.setValue(status['percent_complete']) if status['status'] == "COMPLETE": self.task_combo.setItemIcon(self.task_combo.findText(task_ref), self.icon_completed) self.timer.stop()
class SubFileDialog(QFileDialog): def __init__(self, parent = None, caption = "", directory = "", filter = ""): super().__init__(parent, caption, directory, filter) self.setOption(QFileDialog.DontUseNativeDialog) def _initAllSubFormats(self, formatList): self._formats = {} for f in formatList: self._formats[f.NAME] = f def _addEncodingsBox(self, row, addAuto): mainLayout = self.layout() encodingLabel = QLabel(_("File encoding:"), self) self._encodingBox = QComboBox(self) if addAuto is True: self._encodingBox.addItem(AUTO_ENCODING_STR) self._encodingBox.addItems(ALL_ENCODINGS) self._encodingBox.setToolTip(_("Change file encoding")) self._encodingBox.setEditable(True) mainLayout.addWidget(encodingLabel, row, 0) mainLayout.addWidget(self._encodingBox, row, 1) def _addFormatBox(self, row, formatList): self._initAllSubFormats(formatList) displayedFormats = list(self._formats.keys()) displayedFormats.sort() mainLayout = self.layout() formatLabel = QLabel(_("Subtitle format:"), self) self._formatBox = QComboBox(self) self._formatBox.addItems(displayedFormats) mainLayout.addWidget(formatLabel, row, 0) mainLayout.addWidget(self._formatBox, row, 1) def getEncoding(self): encoding = self._encodingBox.currentText() if encoding == AUTO_ENCODING_STR: encoding = None return encoding def setEncoding(self, encoding): index = self._encodingBox.findText(encoding) self._encodingBox.setCurrentIndex(index) def getSubFormat(self): return self._formats.get(self._formatBox.currentText()) def setSubFormat(self, subFormat): for key, val in self._formats.items(): if val == subFormat: index = self._formatBox.findText(key) self._formatBox.setCurrentIndex(index) return
def create_handbrake_group(self): handbrake_group = QGroupBox('Handbrake Settings') handbrake_layout = QGridLayout() handbrake_path_label = QLabel('Executable:') self.handbrake_path_edit = QLineEdit(self.settings_object['handbrake']['handbrake_path']) handbrake_path_browse_button = QPushButton('Browse') handbrake_path_browse_button.clicked.connect(self.browse_handbrake_path) self.handbrake_path_edit.textEdited.connect(self.set_handbrake_path) handbrake_format_label = QLabel('Format:') handbrake_format_dropdown = QComboBox() handbrake_format_dropdown.addItems(self.FORMAT_VALUES) current_format = self.settings_object['handbrake']['output_format'] if current_format in self.FORMAT_VALUES: handbrake_format_dropdown.setCurrentIndex(handbrake_format_dropdown.findText(current_format)) else: raise SyntaxError('Format "{}" found in settings file is not a supported output format!') handbrake_format_dropdown.currentTextChanged.connect( lambda text: self.parent.enqueue_change('handbrake', 'output_format', text) ) handbrake_encoder_label = QLabel('Encoder:') handbrake_encoder_dropdown = QComboBox() handbrake_encoder_dropdown.addItems(self.ENCODER_VALUES) current_encoder = self.settings_object['handbrake']['encoder'] if current_encoder in self.ENCODER_VALUES: handbrake_encoder_dropdown.setCurrentIndex(handbrake_encoder_dropdown.findText(current_encoder)) else: raise SyntaxError('Encoder "{}" found in settings file is not a supported encoder!') handbrake_encoder_dropdown.currentTextChanged.connect( lambda text: self.parent.enqueue_change('handbrake', 'encoder', text) ) handbrake_quality_label = QLabel('Quality:') handbrake_quality_spinner = QSpinBox() handbrake_quality_spinner.setValue(int(self.settings_object['handbrake']['quality'])) handbrake_quality_spinner.setMinimum(1) handbrake_quality_spinner.setMaximum(30) handbrake_quality_spinner.valueChanged.connect( lambda value: self.parent.enqueue_change('handbrake', 'quality', value) ) handbrake_layout.addWidget(handbrake_path_label, 0, 0) handbrake_layout.addWidget(self.handbrake_path_edit, 0, 1) handbrake_layout.addWidget(handbrake_path_browse_button, 0, 2) handbrake_layout.addWidget(handbrake_format_label, 1, 0) handbrake_layout.addWidget(handbrake_format_dropdown, 1, 1) handbrake_layout.addWidget(handbrake_encoder_label, 2, 0) handbrake_layout.addWidget(handbrake_encoder_dropdown, 2, 1) handbrake_layout.addWidget(handbrake_quality_label, 3, 0) handbrake_layout.addWidget(handbrake_quality_spinner, 3, 1) handbrake_group.setLayout(handbrake_layout) return handbrake_group
def setEditorData(self, editor: QtWidgets.QComboBox, index: QtCore.QModelIndex): editor.blockSignals(True) dflist = index.internalPointer() # type: DFItemList item = dflist[index.row()] # type: DFItem column = index.column() if column == 1: editor.setCurrentIndex(editor.findText(str(item.x_accessor))) elif column == 2: editor.setCurrentIndex(editor.findText(str(item.y_accessor))) elif column == 3: editor.setCurrentIndex(editor.findText(str(item.z_accessor))) editor.blockSignals(False)
def __init__(self, parent=None, *args, **kwargs): super(SettingsForm, self).__init__(parent, *args, **kwargs) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle('Settings') self.setModal(True) self.resize(240, 120) label = QLabel('Old Style (Username/Password)?') old_checkbox = QCheckBox( checked=KeyValue.get('old_style')) label2 = QLabel('Evaluation Type') box = QComboBox() box.addItems(EVALUATION_CHOICES) index = box.findText( KeyValue.get('evaluation_type'), QtCore.Qt.MatchFixedString) if not index < 0: box.setCurrentIndex(index) ok_button = QPushButton('OK') ok_button.setFixedWidth(90) layout = QGridLayout() layout.addWidget(label, 1, 1) layout.addWidget(old_checkbox, 1, 2) layout.addWidget(label2, 2, 1) layout.addWidget(box, 2, 2) layout.addWidget(ok_button, 3, 1, 3, 2, QtCore.Qt.AlignCenter) old_checkbox.stateChanged.connect( lambda: self.set_old_style(old_checkbox)) box.currentIndexChanged.connect(lambda: self.set_eval_type(box)) ok_button.clicked.connect(self.close) self.setLayout(layout)
class WinForm(QWidget): """主窗口""" def __init__(self, parent=None): super().__init__(parent=parent) self.setWindowTitle("设置窗口的样式") self.resize(200, 100) self.label_style = QLabel("设置 Style:") self.combobox_style = QComboBox() # 从QStyleFactory中增加多个显示样式 self.combobox_style.addItems(QStyleFactory.keys()) # 选择当前窗口风格 index = self.combobox_style.findText(QApplication.style().objectName(), Qt.MatchFixedString) # 设置当前窗口风格 self.combobox_style.setCurrentIndex(index) # 通过combobox控件选择窗口风格 self.combobox_style.activated[str].connect(self.handle_style_change) h_layout = QHBoxLayout() h_layout.addWidget(self.label_style) h_layout.addWidget(self.combobox_style) self.setLayout(h_layout) def handle_style_change(self, style): """让整个应用都应用这个风格, 参数style是可用的风格名""" # QApplication.setStyle(style) qstyle = QStyleFactory.create(style) QApplication.setStyle(qstyle)
def setEditorData(self, editor: QComboBox, index: QtCore.QModelIndex) -> None: stl = index.data(Qt.EditRole) editor.addItems(StlDelegate.items) stlIndex = editor.findText(stl) if stlIndex > -1: editor.setCurrentIndex(stlIndex)
def __init__(self, dbmanager, datas, parent=None): super().__init__(parent=parent) self.UI = Ui_ImportMatchDialog() self.UI.setupUi(self) for data in datas: self.data_match[data] = "" self.dbMan = dbmanager # Load participants self.participants = self.dbMan.get_all_participants() # Fill table with datas for data in datas: row = self.UI.tableMatch.rowCount() self.UI.tableMatch.setRowCount(row + 1) item = QTableWidgetItem(data) self.UI.tableMatch.setItem(row, 0, item) item_combo = QComboBox() self.fill_participant_combobox(item_combo) item_combo.setCurrentIndex(item_combo.findText(data)) self.UI.tableMatch.setCellWidget(row, 1, item_combo) # Connect signals / slots self.UI.btnOK.clicked.connect(self.ok_clicked) self.UI.btnCancel.clicked.connect(self.cancel_clicked) self.UI.btnAddParticipant.clicked.connect( self.new_participant_requested) # Init participant dialog self.part_diag = QDialog(parent=self)
class EditEnumValue(QWidget): def __init__(self, value): super().__init__() self._val = value self._rootLayout = QHBoxLayout() self._rootLayout.addStretch() self._comboBox = QComboBox() for item in self._val.getTable(): self._comboBox.addItem(item) self._comboBox.currentTextChanged.connect( self._signal_comboBox_textChanged) self._rootLayout.addWidget(self._comboBox) self._rootLayout.setContentsMargins(1, 1, 1, 1) self.setLayout(self._rootLayout) self._pull() def _signal_comboBox_textChanged(self, text): self._push(text) self._pull() def _push(self, text): self._val.setVal(text) def _pull(self): idx = self._comboBox.findText(self._val.getVal()) if idx == -1: raise RuntimeError("Can't find value '{0}' in combo box".format( self._val.getVal())) self._comboBox.setCurrentIndex(idx)
def refresh_table(self): self._manual_change = True self._custom_fields = list( self._configuration.scheduler_info.data.keys()) labels = self._header + self._custom_fields self.setRowCount(len(labels)) self.setVerticalHeaderLabels(labels) self.horizontalHeader().setStretchLastSection(False) header = self.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(1, QHeaderView.Interactive) #header.setSectionResizeMode(2, QHeaderView.Interactive) self.horizontalHeader().hide() combo = QComboBox() combo.addItems(['Custom scheduler...'] + list(get_schedulers())) self.setCellWidget(0, 0, combo) self.setSpan(0, 0, 1, 2) name = self._configuration.scheduler_info.filename scheduler_item = QTableWidgetItem(name and os.path.relpath( name, self._configuration.cur_dir)) scheduler_item.setFlags(scheduler_item.flags() ^ (Qt.ItemIsEditable)) self.setItem(1, 0, scheduler_item) self._btn_open = QPushButton(self) self._btn_open.setText('Open') self._btn_open.clicked.connect(self._open_scheduler) self.setCellWidget(1, 1, self._btn_open) combo.currentIndexChanged['QString'].connect(self._select_scheduler) if self._configuration.scheduler_info.clas: i = combo.findText(self._configuration.scheduler_info.clas) if i <= 0: i = 0 combo.setCurrentIndex(i) self.setItem( 2, 0, QTableWidgetItem(str( self._configuration.scheduler_info.overhead)) ) self.setSpan(2, 0, 1, 2) self.setItem( 3, 0, QTableWidgetItem(str( self._configuration.scheduler_info.overhead_activate)) ) self.setSpan(3, 0, 1, 2) self.setItem( 4, 0, QTableWidgetItem(str( self._configuration.scheduler_info.overhead_terminate)) ) self.setSpan(4, 0, 1, 2) i = 5 for name, value in self._configuration.scheduler_info.data.items(): self.setItem(i, 0, QTableWidgetItem(str(value))) self.setSpan(i, 0, 1, 2) i += 1
def append_to_combobox(cbox: QComboBox): current = cbox.currentText() completions = set(cbox.itemText(i) for i in range(cbox.count())) completions.add(current) cbox.clear() cbox.addItems(completions) cbox.setCurrentIndex(cbox.findText(current))
def add_dropdown(self, name, options, suboptions=None, default=None, alphabetical=True): if alphabetical: options.sort() combo_box = QComboBox() combo_box.addItem("Any") combo_box.addItems(options) if suboptions is not None: sub_combo_box = QComboBox() sub_combo_box.setHidden(True) else: sub_combo_box = None label = QLabel(name) self.filter_names.append(name) self.layout.addWidget(label) self.layout.addWidget(combo_box) if suboptions is not None: self.layout.addWidget(sub_combo_box) sub_combo_box.currentIndexChanged.connect( lambda: self.set_sub_filters(name, combo_box, sub_combo_box)) combo_box.currentIndexChanged.connect(lambda: self.set_filters( name, combo_box, sub_combo_box, suboptions)) if default is not None: index = combo_box.findText(default, QtCore.Qt.MatchFixedString) if index >= 0: combo_box.setCurrentIndex(index)
def SettingDialog(self): from PyQt5.QtWidgets import (QDialog, QSpinBox, QComboBox, QDialogButtonBox, QFormLayout) dialog = QDialog(self.qb) boxDifficult = QSpinBox(dialog) boxDifficult.setRange(1, 5) boxDifficult.setValue(self.Difficult) boxWhoFirst = QComboBox(dialog) boxWhoFirst.addItems(['player', 'AI', 'random']) boxWhoFirst.setCurrentIndex(boxWhoFirst.findText(self.WhoFirst)) buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, dialog) form = QFormLayout(dialog) form.addRow(QLabel("设置:")) form.addRow("难度(1-5):", boxDifficult) form.addRow("先手:", boxWhoFirst) form.addRow(buttonBox) buttonBox.accepted.connect(dialog.accept) buttonBox.rejected.connect(dialog.reject) if dialog.exec() == QDialog.Accepted: self.Difficult = boxDifficult.value() self.WhoFirst = boxWhoFirst.currentText()
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
def addCombobox(self, tableview, tablemodel, etype, cbdata, row, column, arguments, searchtext=None): item = tableview.model().item(row, column) cbDelegate = QComboBox() cbDelegate.currentIndexChanged[str].connect(item.setText) #cbDelegate.currentIndexChanged[str].connect(lambda: self.Combo_indexchanged(etype, arguments)) cbDelegate.activated[str].connect( lambda: self.Combo_indexchanged(etype, arguments)) #print(cbdata) cbDelegate.addItems(cbdata) cbDelegate.setProperty('row', row) cbDelegate.setProperty('column', column) tableview.setIndexWidget(item.index(), cbDelegate) #tablemodel.item(row, column).setEditable(True) tableview.openPersistentEditor(tablemodel.index(row, column)) tableview.setEditTriggers(QAbstractItemView.NoEditTriggers) if searchtext: index = cbDelegate.findText(searchtext, Qt.MatchFixedString) if index >= 0: cbDelegate.setCurrentIndex(index)
def _add_task_to_table(self, row, task): self._ignore_cell_changed = True self.setItem(row, self._dict_header['id'], QTableWidgetItem(str(task.identifier))) self.item(row, self._dict_header['id']) \ .setTextAlignment(Qt.AlignCenter) self.setItem(row, self._dict_header['name'], QTableWidgetItem(str(task.name))) combo = QComboBox() items = [task_type for task_type in Task.task_types_names] combo.addItems(items) combo.setCurrentIndex(combo.findText(task.task_type)) combo.currentIndexChanged.connect( lambda x: self._cell_changed(row, self._dict_header['task_type'])) self.setCellWidget(row, self._dict_header['task_type'], combo) item = QTableWidgetItem(task.abort_on_miss and 'Yes' or 'No') item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsSelectable) item.setCheckState(task.abort_on_miss and Qt.Checked or Qt.Unchecked) self.setItem(row, self._dict_header['abort'], item) self.setItem( row, self._dict_header['list_activation_dates'], QTableWidgetItem(', '.join(map(str, task.list_activation_dates)))) self.item(row, self._dict_header['list_activation_dates']) \ .setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) for i in [ 'activation_date', 'period', 'deadline', 'wcet', 'base_cpi', 'n_instr', 'mix', 'acet', 'et_stddev', 'preemption_cost', 'p_et' ]: self.setItem(row, self._dict_header[i], QTableWidgetItem(str(task.__dict__[i]))) self.item(row, self._dict_header[i]) \ .setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) stack_item = QTableWidgetItem(str(task.stack_file)) stack_item.setFlags(stack_item.flags() ^ (Qt.ItemIsEditable)) self.setItem(row, self._dict_header['sdp'], stack_item) combo = QComboBox() combo.currentIndexChanged.connect( lambda x: self._cell_changed(row, self._dict_header['followed'])) self.setCellWidget(row, self._dict_header['followed'], combo) for col in range(len(self._custom_fields)): key = self._custom_fields[col] if key in task.data and task.data[key] is not None: item = QTableWidgetItem(str(task.data[key])) else: item = QTableWidgetItem('') item.setBackgroundColor(QColor.fromRgb(200, 255, 200)) self.setItem(row, col + len(self._header), item) self._ignore_cell_changed = False self._show_period(task, row)
def newNoteSelector(self): comboBox = QComboBox() comboBox.addItems(basicNotes) index = comboBox.findText(self.noteName, QtCore.Qt.MatchFixedString) comboBox.setCurrentIndex(index) comboBox.setFixedWidth(col0Width) comboBox.currentIndexChanged.connect(self.changeBaseNoteByIndex) return comboBox
class SceneTransitionTab(QWidget): def __init__(self): super().__init__() self._ledit_duration = QLineEdit() self._cbox_type = QComboBox() self._res = ResourceManager() self.init_ui() @staticmethod def transition_type_to_text(transition_type: TransitionType) -> str: return transition_type.name.capitalize() @staticmethod def text_to_transition_type(text: str) -> TransitionType: return TransitionType[text.upper()] def load_data_on_ui(self, scene: Scene) -> None: self._ledit_duration.setText(str(scene.duration)) idx = self._cbox_type.findText( self.transition_type_to_text(scene.transition_type)) self._cbox_type.setCurrentIndex(idx) def init_ui(self) -> None: vbox_duration = QVBoxLayout() vbox_duration.addWidget(self._ledit_duration) group_duration = QGroupBox(self._res['sceneDurationLabel']) group_duration.setLayout(vbox_duration) transitions = [ self.transition_type_to_text(TransitionType.NONE), self.transition_type_to_text(TransitionType.PUSH), self.transition_type_to_text(TransitionType.FADE) ] self._cbox_type.addItems(transitions) vbox_transition = QVBoxLayout() vbox_transition.addWidget(self._cbox_type) group_transition = QGroupBox(self._res['sceneTransitionLabel']) group_transition.setLayout(vbox_transition) vbox_outmost = QVBoxLayout() vbox_outmost.addWidget(group_duration) vbox_outmost.addWidget(group_transition) vbox_outmost.addStretch(1) self.setLayout(vbox_outmost) def save(self, scene: Scene) -> None: scene.duration = int(self._ledit_duration.text()) transition = self._cbox_type.currentText() scene.transition_type = self.text_to_transition_type(transition) def is_data_valid(self) -> bool: return self._ledit_duration.text().isdigit()
class tb_spectrum(QWidget): def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout() label = QLabel(_("Solar spectrum") + ":") self.layout.addWidget(label) self.cb = QComboBox() self.cb.activated.connect(self.on_cb_model_changed) self.layout.addWidget(self.cb) self.update() self.setLayout(self.layout) self.show() def get_text(self): out = self.cb.currentText() out = out.split(" ")[0] return out def file_name_set_start(self, start): self.start = start def file_name_set_end(self, end): self.end = end def find_models(self): ret = [] path = get_plugins_path() for file in glob.glob(os.path.join(path, "*")): file_name = os.path.basename(file) if file_name.startswith("light_"): if file_name.endswith(".dll") or file_name.endswith(".so"): ret.append( os.path.splitext(os.path.basename(file_name[6:]))[0]) return ret def on_cb_model_changed(self): cb_text = self.cb.currentText() inp_update_token_value("light.inp", "#sun", cb_text) def update(self): self.cb.blockSignals(True) models = find_light_source() for i in range(0, len(models)): self.cb.addItem(models[i]) used_model = inp_get_token_value("light.inp", "#sun") if models.count(used_model) == 0: used_model = "sun" inp_update_token_value("light.inp", "#sun", "sun") self.cb.setCurrentIndex(self.cb.findText(used_model)) #scan_item_add("light.inp","#sun","Light source",1) self.cb.blockSignals(False)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('SEASide') self.resize(1000, 560) # Connection self._config = Configuration() server_names = tuple(sorted(SERVERS.keys())) # Interface self._widg = QWidget(self) self.setCentralWidget(self._widg) # Server selection dropdown self._dropdown = QComboBox() self._dropdown.addItems(server_names) default_server_name = self._config.get_default_server() self._dropdown.setCurrentIndex( self._dropdown.findText(default_server_name)) # Connect button self._button = QPushButton('Connect') self._button.clicked.connect(self._new_tab) # Tab view self._tab_view = QTabWidget() self._tab_view.setTabsClosable(True) self._tab_view.tabCloseRequested.connect(self._close_tab) # Default tab default_tab = MasterTab(SERVERS[self._config.get_default_server()], self._config) self._tab_view.addTab(default_tab, default_server_name) # Layout setup conn_layout = QHBoxLayout() top_layout = QVBoxLayout() # conn_layout.addStretch(1) conn_layout.addWidget(self._button) conn_layout.addWidget(self._dropdown) conn_widg = QWidget() conn_widg.setLayout(conn_layout) top_layout.addWidget(conn_widg) top_layout.addWidget(self._tab_view) self._widg.setLayout(top_layout) @pyqtSlot() def _new_tab(self): server_name = str(self._dropdown.currentText()) server = SERVERS[server_name] self._config.set_default_server(server_name) tab = MasterTab(server, self._config) self._tab_view.addTab(tab, server_name) self._tab_view.setCurrentIndex(self._tab_view.count() - 1) @pyqtSlot(int) def _close_tab(self, index): conn = self._tab_view.widget(index).get_connection() conn.close_connection() self._tab_view.removeTab(index) def get_username(self): return self._config.get_username()
def _add_task_to_table(self, row, task): self._ignore_cell_changed = True self.setItem(row, self._dict_header['id'], QTableWidgetItem(str(task.identifier))) self.item(row, self._dict_header['id']) \ .setTextAlignment(Qt.AlignCenter) self.setItem(row, self._dict_header['name'], QTableWidgetItem(str(task.name))) combo = QComboBox() items = [task_type for task_type in Task.task_types_names] combo.addItems(items) combo.setCurrentIndex(combo.findText(task.task_type)) combo.currentIndexChanged.connect( lambda x: self._cell_changed(row, self._dict_header['task_type'])) self.setCellWidget(row, self._dict_header['task_type'], combo) item = QTableWidgetItem(task.abort_on_miss and 'Yes' or 'No') item.setFlags( Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsSelectable) item.setCheckState(task.abort_on_miss and Qt.Checked or Qt.Unchecked) self.setItem(row, self._dict_header['abort'], item) self.setItem(row, self._dict_header['list_activation_dates'], QTableWidgetItem( ', '.join(map(str, task.list_activation_dates)))) self.item(row, self._dict_header['list_activation_dates']) \ .setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) for i in ['activation_date', 'period', 'deadline', 'wcet', 'base_cpi', 'n_instr', 'mix', 'acet', 'et_stddev', 'preemption_cost']: self.setItem(row, self._dict_header[i], QTableWidgetItem(str(task.__dict__[i]))) self.item(row, self._dict_header[i]) \ .setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) stack_item = QTableWidgetItem(str(task.stack_file)) stack_item.setFlags(stack_item.flags() ^ (Qt.ItemIsEditable)) self.setItem(row, self._dict_header['sdp'], stack_item) combo = QComboBox() combo.currentIndexChanged.connect( lambda x: self._cell_changed(row, self._dict_header['followed'])) self.setCellWidget(row, self._dict_header['followed'], combo) for col in range(len(self._custom_fields)): key = self._custom_fields[col] if key in task.data and task.data[key] is not None: item = QTableWidgetItem(str(task.data[key])) else: item = QTableWidgetItem('') item.setBackgroundColor(QColor.fromRgb(200, 255, 200)) self.setItem(row, col + len(self._header), item) self._ignore_cell_changed = False self._show_period(task, row)
def mnemonize(self): num = self.num.text() lang = self.lang.currentText() if self.conn is not None: self.conn.commit() self.conn.close() self.conn = sqlite3.connect(langs[lang]['db']) c = self.conn.cursor() self.pb.setMaximum(2**(len(num) - 1)) self.pb.setValue(0) self.pb.setStyleSheet('QProgressBar::chunk {background: blue;}') r = self.longestMnemo(num) m = len(min(r, key=len)) self.v = {} self.scroll.setWidgetResizable(True) self.scroll.setFixedHeight(800) self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scrollCont = QWidget(self.scroll) self.scroll.setWidget(self.scrollCont) self.vbox = QVBoxLayout() self.pb.setValue(0) self.pb.setStyleSheet('QProgressBar::chunk {background: green;}') self.pb.setMaximum(len(r) - 1) for i, y in enumerate(r): self.pb.setValue(i) if len(y) - m < 2: hboxH = QHBoxLayout() hbox = QHBoxLayout() for x in y: L = QLabel(x) if len(y) == m: L.setStyleSheet("QLabel {color: red}") hboxH.addWidget(L) C = QComboBox() c.execute(langs[lang]['query'], [x]) for s in c: C.addItem(s[0]) c.execute(langs[lang]['default'], [x]) r = c.fetchone() if r != None: C.setCurrentIndex(C.findText(r[0])) else: C.setStyleSheet("background: blue") C.activated.connect(self.updateMnemo) if not x in self.v: self.v[x] = [] self.v[x].append(C) hbox.addWidget(C) self.vbox.addLayout(hboxH) self.vbox.addLayout(hbox) self.scrollCont.setLayout(self.vbox) self.pb.setValue(0)
def obsChanged(self): #Nomainot observation nomaina visus texta laukus if len(self.observationList.selectedItems()) > 0: item = self.observationList.currentItem() plannedObs = item.data(Qt.UserRole) self.nameBox.setText(plannedObs.name) self.priorityBox.setText(str(plannedObs.priority)) self.obsBox.setText(str(plannedObs.obs_per_week)) self.scanBox.setText(str(plannedObs.scans_per_obs)) i = 0 maxi = self.targetLayout.count() while(i < maxi): layout_item = self.targetLayout.itemAt(i) if layout_item in self.dateBoxList: self.deleteItemsOfLayout(layout_item.layout()) self.targetLayout.removeItem(layout_item) self.dateBoxList.remove(layout_item) maxi = self.targetLayout.count() i = i -1 i=i+1 self.dateBoxList.clear() self.targetTimesCount = 0 if plannedObs.times: checkedDates = [] for index in range(self.dateList.count()): if self.dateList.item(index).checkState() == Qt.Checked: checkedDates.append(self.dateList.item(index).text()) print(checkedDates) for time in list(plannedObs.times): print(time) if time not in checkedDates: #Ja observation pievienots specifisks laiks datumam kurs vairs netiks izmantots to pazino lietotajam self.show_error("Date mismatch", "Date "+time+" is not checked, removing it") plannedObs.times.remove(time) for time in list(plannedObs.times): line = QHBoxLayout() dateBox = QComboBox() for index in range(self.dateList.count()): if self.dateList.item(index).checkState() == Qt.Checked: #Specific laikiem pievieno tikai datumus kas izveleti pie dates dateBox.addItem(self.dateList.item(index).text(), self.dateList.item(index).data(Qt.UserRole)) dateBox.addItem("Remove") dateBox.currentTextChanged.connect(self.timeChanged) self.targetTimesCount += 1 dateBox.sizePolicy().setHorizontalStretch(1) timeBox = QLineEdit(plannedObs.times[time]) timeBox.sizePolicy().setHorizontalStretch(3) line.addWidget(dateBox) line.addWidget(timeBox) self.dateBoxList.append(line) self.targetLayout.insertLayout(self.targetLayout.count() - 2, line) dateBox.setCurrentIndex(dateBox.findText(time)) else: self.nameBox.setText("") self.priorityBox.setText("") self.obsBox.setText("") self.scanBox.setText("") self.targetTimesCount = 0
def __init__(self, old_name: str, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('Rename gesture') layout = QVBoxLayout() self.setLayout(layout) old_name_layout = QHBoxLayout() old_name_layout.addWidget(QLabel('Old name:')) old_name_layout.addWidget(QLabel(old_name)) layout.addLayout(old_name_layout) new_type_layout = QHBoxLayout() edit_name_layout = QHBoxLayout() layout.addLayout(edit_name_layout) new_name_layout = QHBoxLayout() layout.addLayout(new_name_layout) new_name_layout.addWidget(QLabel('New name:')) self.new_name_label = QLabel(old_name) new_name_layout.addWidget(self.new_name_label) self.new_name_parts = [ QLineEdit(part) for part in old_name.split(cn.FILE_NAME_SEPARATOR) ] new_type_layout.addWidget(QLabel('Change gesture type:')) new_type_combo_box = QComboBox() new_type_combo_box.addItems(cn.GESTURES) # This may cause weird behaviour if you name files maliciously, but we ignore that for now if len(old_name.split(cn.FILE_NAME_SEPARATOR)) > cn.GESTURE_NAME_TYPE_INDEX: layout.addLayout(new_type_layout) escaped_name = self.new_name_parts[cn.GESTURE_NAME_TYPE_INDEX].text() if escaped_name in cn.ESCAPED_TO_NICE_GESTURES: nice_name = cn.ESCAPED_TO_NICE_GESTURES[escaped_name] new_type_combo_box.setCurrentIndex(new_type_combo_box.findText(nice_name)) new_type_combo_box.currentTextChanged.connect(self.change_gesture_type) new_type_layout.addWidget(new_type_combo_box) for i, part_line_edit in enumerate(self.new_name_parts): part_line_edit.textEdited.connect(self.refresh_new_name) edit_name_layout.addWidget(part_line_edit, stretch=([1, 5, 3, 3][i:i + 1] + [2])[0]) confirm_button = QPushButton('Confirm') confirm_button.clicked.connect(self.confirm_rename) layout.addWidget(confirm_button) layout.setContentsMargins(5, 5, 5, 5) layout.setSpacing(5) self.old_name = old_name
def setup_combo_completer(combo_widget: QtWidgets.QComboBox): combo_widget.setEditable(True) combo_widget.setInsertPolicy(QtWidgets.QComboBox.NoInsert) combo_widget.lineEdit().editingFinished.connect( lambda: combo_widget.setCurrentIndex( combo_widget.findText(combo_widget.currentText()))) completer = combo_widget.completer() completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion) completer.popup().setAlternatingRowColors(True) completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) completer.setFilterMode(QtCore.Qt.MatchContains)
def update_annotation(self, child: QTreeWidgetItem, cbox: QComboBox): """ On getting a change signal from the parameter option combobox, set options on the volume.annotations object Also set the selected row to active Parameters ---------- child: is the node in the QTreeWidget that corresponds to our paramter option selection cbox: Qt combobox that was clicked row: The row of the qtreewidget where the combobox is """ vol = self.controller.current_annotation_volume() if not vol: error_dialog(self, "Error", "No volume selected") return try: x = int(self.ui.labelXPos.text()) y = int(self.ui.labelYPos.text()) z = int(self.ui.labelZPos.text()) except ValueError: x = y = z = None base_node = child term = base_node.text(1) option = cbox.currentText() # If we are updating the annotation to ImageOnly, we should wipe any coordinates that may have been added to # a previous annotation option. if option == 'imageOnly': x = y = z = None elif option in (centre_stage_options.opts['options_requiring_points']): if None in (x, y, z): info_dialog( self, 'Select a region!', "For option '{}' coordinates must be specified".format( option)) # this will reset the option back to what it is on the volume.annotation object cbox.setCurrentIndex( cbox.findText( vol.annotations.get_by_term(term).selected_option)) return if not term: error_dialog(self, "Error", "No term is selected!") return vol.annotations.update_annotation(term, x, y, z, option) self.on_tree_clicked(base_node) # We are now autosaving. so save on each annotation term changed self.save_annotations(suppress_msg=True)
class ViewSettingsPage(QWidget): def __init__(self, share_dir, parent=None): QWidget.__init__(self, parent) layout = QFormLayout() self.show_notation = QCheckBox(self) layout.addRow(_("Show fields notation"), self.show_notation) self.show_possible_moves = QCheckBox(self) layout.addRow(_("Show possible moves"), self.show_possible_moves) self.theme = QComboBox(self) self.themes = dict() for theme in Theme.list_themes(share_dir): self.themes[theme.id] = theme self.theme.addItem(theme.name, theme.id) layout.addRow(_("Theme"), self.theme) self.enable_sound = QCheckBox(self) layout.addRow(_("Enable sounds"), self.enable_sound) self.setLayout(layout) def get_theme(self): theme_name = self.theme.currentData() return self.themes[theme_name] def get_enable_sound(self): return self.enable_sound.checkState() == Qt.Checked def load(self, settings): show_notation = settings.value("show_notation", type=bool) self.show_notation.setCheckState( Qt.Checked if show_notation else Qt.Unchecked) show_possible_moves = settings.value("show_possible_moves", type=bool) self.show_possible_moves.setCheckState( Qt.Checked if show_possible_moves else Qt.Unchecked) theme = settings.value("theme") theme_idx = self.theme.findData(theme) if theme_idx < 0: theme_idx = self.theme.findText("default") if theme_idx >= 0: self.theme.setCurrentIndex(theme_idx) enable_sound = settings.value("enable_sound", type=bool) self.enable_sound.setCheckState( Qt.Checked if enable_sound else Qt.Unchecked) def save(self, settings): settings.setValue("show_notation", self.show_notation.checkState() == Qt.Checked) settings.setValue("show_possible_moves", self.show_possible_moves.checkState() == Qt.Checked) settings.setValue("theme", self.theme.currentData()) settings.setValue("enable_sound", self.get_enable_sound())
def buildComboActions(self, row, value=None): # create combo combo_actions = QComboBox(self) combo_actions.addItems(self.listcomboactions) #combo_actions.currentIndexChanged.connect(lambda n=row: self.onComboChanged(row)) i = self.tbl_viewactions.model().index(row, 0) self.tbl_viewactions.setIndexWidget(i, combo_actions) # select value if value is not None: index = combo_actions.findText(value, Qt.MatchFixedString) if index >= 0: combo_actions.setCurrentIndex(index)
def createEditor( self, parent: QWidget, option: QStyleOptionViewItem, idx: QModelIndex, ): values = idx.model().data(idx, Qt.UserRole + 10) # TODO:Need to change this to not be hard-coded. if values is None: return super().createEditor(parent, option, idx) cb = QComboBox(parent) cb.addItems(values) currentText = idx.model().data(idx, Qt.DisplayRole) editorIdx = cb.findText(currentText) cb.setCurrentIndex(editorIdx) return cb
class ConfigSetting(QWidget): def __init__(self, settingName, settingType, **kwargs): super().__init__() self.settingType = settingType mainLayout = QHBoxLayout() self.setLayout(mainLayout) mainLayout.addWidget(QLabel(settingName)) if settingType == "check": self.settingInput = QCheckBox() self.settingInput.setChecked(True) elif settingType == "line": self.settingInput = QLineEdit() elif settingType == "dropdown": self.settingInput = QComboBox() if kwargs.get("dropdownOptions", None): for i in kwargs["dropdownOptions"]: self.settingInput.addItem(i) else: print("No options were provided for setting \'" + settingName + "\'") mainLayout.addWidget(self.settingInput) if kwargs.get("tooltip", None): self.setToolTip(kwargs["tooltip"]) def setSetting(self, setting): if self.settingType == "check": if setting == "1": self.settingInput.setChecked(True) elif setting == "0": self.settingInput.setChecked(False) elif self.settingType == "line": self.settingInput.setText(setting) elif self.settingType == "dropdown": self.settingInput.setCurrentIndex( self.settingInput.findText(setting)) def getSetting(self): if self.settingType == "check": if self.settingInput.isChecked(): return "1" else: return "0" elif self.settingType == "line": return self.settingInput.text() elif self.settingType == "dropdown": return self.settingInput.currentText()
def update_annotation(self, child: QTreeWidgetItem, cbox: QComboBox): """ On getting a change signal from the parameter option combobox, set options on the volume.annotations object Also set the selected row to active Parameters ---------- child: is the node in the QTreeWidget that corresponds to our paramter option selection cbox: Qt combobox that was clicked row: The row of the qtreewidget where the combobox is """ vol = self.controller.current_annotation_volume() if not vol: error_dialog(self, "Error", "No volume selected") return try: x = int(self.ui.labelXPos.text()) y = int(self.ui.labelYPos.text()) z = int(self.ui.labelZPos.text()) except ValueError: x = y = z = None base_node = child term = base_node.text(1) option = cbox.currentText() # If we are updating the annotation to ImageOnly, we should wipe any coordinates that may have been added to # a previous annotation option. if option == 'imageOnly': x = y = z = None elif option in (centre_stage_options.opts['options_requiring_points']): if None in (x, y, z): info_dialog(self, 'Select a region!', "For option '{}' coordinates must be specified".format(option)) # this will reset the option back to what it is on the volume.annotation object cbox.setCurrentIndex(cbox.findText(vol.annotations.get_by_term(term).selected_option)) return if not term: error_dialog(self, "Error", "No term is selected!") return vol.annotations.update_annotation(term, x, y, z, option) self.on_tree_clicked(base_node) # We are now autosaving. so save on each annotation term changed self.save_annotations(suppress_msg=True)
def add_row(self,pos,start,width,depth,voltage,active): pos= tab_insert_row(self.tab) self.tab.blockSignals(True) self.tab.setItem(pos,0,QTableWidgetItem(start)) self.tab.setItem(pos,1,QTableWidgetItem(width)) self.tab.setItem(pos,2,QTableWidgetItem(depth)) self.tab.setItem(pos,3,QTableWidgetItem(voltage)) combobox = QComboBox() combobox.addItem(_("true")) combobox.addItem(_("false")) self.tab.setCellWidget(pos,4, combobox) combobox.setCurrentIndex(combobox.findText(active.lower())) combobox.currentIndexChanged.connect(self.save) self.tab.blockSignals(False)
class CSVOptionsWindow(QWidget): def __init__(self, mainwindow): QWidget.__init__(self, mainwindow, Qt.Window) self._setupUi() self.doc = mainwindow.doc self.model = mainwindow.model.csv_options self.tableModel = CSVOptionsTableModel(self.model, self.tableView) self.model.view = self self.encodingComboBox.addItems(SUPPORTED_ENCODINGS) self.cancelButton.clicked.connect(self.hide) self.continueButton.clicked.connect(self.model.continue_import) self.targetComboBox.currentIndexChanged.connect(self.targetIndexChanged) self.layoutComboBox.currentIndexChanged.connect(self.layoutIndexChanged) self.rescanButton.clicked.connect(self.rescanClicked) def _setupUi(self): self.setWindowTitle(tr("CSV Options")) self.resize(526, 369) self.verticalLayout = QVBoxLayout(self) msg = tr( "Specify which CSV columns correspond to which transaction fields. You must also " "uncheck the \"Import\" column for lines that don\'t represent a transaction " "(header, footer, comments)." ) self.label = QLabel(msg) self.label.setWordWrap(True) self.verticalLayout.addWidget(self.label) self.gridLayout = QGridLayout() self.label_2 = QLabel(tr("Layout:")) self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1) self.layoutComboBox = QComboBox(self) self.layoutComboBox.setMinimumSize(QtCore.QSize(160, 0)) self.gridLayout.addWidget(self.layoutComboBox, 0, 1, 1, 1) self.label_4 = QLabel(tr("Delimiter:")) self.gridLayout.addWidget(self.label_4, 0, 3, 1, 1) self.fieldSeparatorEdit = QLineEdit(self) self.fieldSeparatorEdit.setMaximumSize(QtCore.QSize(30, 16777215)) self.gridLayout.addWidget(self.fieldSeparatorEdit, 0, 4, 1, 1) self.targetComboBox = QComboBox(self) self.gridLayout.addWidget(self.targetComboBox, 1, 1, 1, 1) self.label_3 = QLabel(tr("Target:")) self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1) self.encodingComboBox = QComboBox(self) self.gridLayout.addWidget(self.encodingComboBox, 1, 4, 1, 1) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem, 2, 2, 1, 1) self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setSpacing(0) spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem1) self.rescanButton = QPushButton(tr("Rescan")) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.rescanButton.sizePolicy().hasHeightForWidth()) self.rescanButton.setSizePolicy(sizePolicy) self.horizontalLayout_2.addWidget(self.rescanButton) self.gridLayout.addLayout(self.horizontalLayout_2, 2, 3, 1, 2) self.label_5 = QLabel(tr("Encoding:")) self.gridLayout.addWidget(self.label_5, 1, 3, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.tableView = QTableView(self) self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setShowGrid(False) self.tableView.horizontalHeader().setHighlightSections(False) self.tableView.verticalHeader().setVisible(False) self.tableView.verticalHeader().setDefaultSectionSize(18) self.verticalLayout.addWidget(self.tableView) self.horizontalLayout = QHBoxLayout() spacerItem2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem2) self.cancelButton = QPushButton(tr("Cancel")) self.cancelButton.setShortcut("Esc") self.horizontalLayout.addWidget(self.cancelButton) self.continueButton = QPushButton(tr("Continue Import")) self.continueButton.setDefault(True) self.horizontalLayout.addWidget(self.continueButton) self.verticalLayout.addLayout(self.horizontalLayout) # --- Private def _newLayout(self): title = tr("New Layout") msg = tr("Choose a name for your new layout:") name, ok = QInputDialog.getText(self, title, msg) if ok and name: self.model.new_layout(name) def _renameLayout(self): title = tr("Rename Layout") msg = tr("Choose a name for your layout:") name, ok = QInputDialog.getText(self, title, msg) if ok and name: self.model.rename_selected_layout(name) # --- Event Handling def layoutIndexChanged(self, index): # This one is a little complicated. We want to only be able to select the layouts. If # anything else is clicked, we revert back to the old index. If the item has user data, # it means that an action has to be performed. if index < 0: return elif index < len(self.model.layout_names): layout_name = None if index == 0 else str(self.layoutComboBox.itemText(index)) self.model.select_layout(layout_name) else: self.layoutComboBox.setCurrentIndex(self.layoutComboBox.findText(self.model.layout.name)) data = str(self.layoutComboBox.itemData(index)) if data == NEW_LAYOUT: self._newLayout() elif data == RENAME_LAYOUT: self._renameLayout() elif data == DELETE_LAYOUT: self.model.delete_selected_layout() def rescanClicked(self): self.model.encoding_index = self.encodingComboBox.currentIndex() self.model.field_separator = str(self.fieldSeparatorEdit.text()) self.model.rescan() def targetIndexChanged(self, index): self.model.selected_target_index = index # --- model --> view # hide() is called from the model, but is already covered by QWidget def refresh_columns(self): self.tableModel.beginResetModel() self.tableModel.endResetModel() def refresh_columns_name(self): self.tableModel.refreshColumnsName() def refresh_layout_menu(self): self.layoutComboBox.currentIndexChanged.disconnect(self.layoutIndexChanged) self.layoutComboBox.clear() self.layoutComboBox.addItems(self.model.layout_names) self.layoutComboBox.insertSeparator(self.layoutComboBox.count()) self.layoutComboBox.addItem(tr("New Layout..."), NEW_LAYOUT) self.layoutComboBox.addItem(tr("Rename Selected Layout..."), RENAME_LAYOUT) self.layoutComboBox.addItem(tr("Delete Selected Layout"), DELETE_LAYOUT) self.layoutComboBox.setCurrentIndex(self.layoutComboBox.findText(self.model.layout.name)) self.layoutComboBox.currentIndexChanged.connect(self.layoutIndexChanged) def refresh_lines(self): self.tableModel.beginResetModel() self.tableModel.endResetModel() self.fieldSeparatorEdit.setText(self.model.field_separator) def refresh_targets(self): self.targetComboBox.currentIndexChanged.disconnect(self.targetIndexChanged) self.targetComboBox.clear() self.targetComboBox.addItems(self.model.target_account_names) self.targetComboBox.currentIndexChanged.connect(self.targetIndexChanged) def show(self): # For non-modal dialogs, show() is not enough to bring the window at the forefront, we have # to call raise() as well QWidget.show(self) self.raise_() def show_message(self, msg): title = "Warning" QMessageBox.warning(self, title, msg)
class PropertyFileEditor(QDialog): def __init__(self, subFormats, parent = None): super().__init__(parent) self._settings = SubSettings() self.__createPropertyFilesDirectory() self.__initSubFormats(subFormats) self.__initGui() def __createPropertyFilesDirectory(self): pfileDir = self._settings.getPropertyFilesPath() try: os.makedirs(pfileDir) except OSError as exc: if exc.errno == errno.EEXIST and os.path.isdir(pfileDir): pass else: raise def __initSubFormats(self, formats): self._formats = {} for f in formats: self._formats[f.NAME] = f def __initGui(self): layout = QVBoxLayout() layout.setSpacing(10) layout.addWidget(self._createFpsBox()) layout.addWidget(self._createEncodingBox()) layout.addWidget(self._createFormatBox()) layout.addWidget(self._createButtons()) self.setLayout(layout) self.setWindowTitle(_("Subtitle Properties Editor")) self.setModal(True) # Some signals self._closeButton.clicked.connect(self.close) self._openButton.clicked.connect(self.openProperties) self._saveButton.clicked.connect(self.saveProperties) self._autoEncoding.toggled.connect(self._inputEncoding.setDisabled) self._changeEncoding.toggled.connect(self._outputEncoding.setEnabled) def _createFpsBox(self): groupbox = QGroupBox(_("FPS")) layout = QHBoxLayout() self._autoFps = QCheckBox(_("Auto FPS"), self) self._fps = QComboBox(self) self._fps.addItems(["23.976", "24", "25", "29.97", "30"]) self._fps.setEditable(True) layout.addWidget(self._autoFps) layout.addWidget(self._fps) groupbox.setLayout(layout) return groupbox def _createEncodingBox(self): groupbox = QGroupBox(_("File Encoding")) layout = QGridLayout() self._autoEncoding = QCheckBox(_("Auto input encoding"), self) self._inputEncoding = QComboBox(self) self._inputEncoding.addItems(ALL_ENCODINGS) self._inputEncoding.setDisabled(self._autoEncoding.isChecked()) inputLabel = QLabel(_("Input encoding")) self._changeEncoding = QCheckBox(_("Change encoding on save"), self) self._outputEncoding = QComboBox(self) self._outputEncoding.addItems(ALL_ENCODINGS) self._outputEncoding.setEnabled(self._changeEncoding.isChecked()) outputLabel = QLabel(_("Output encoding")) layout.addWidget(self._autoEncoding, 0, 0) layout.addWidget(self._inputEncoding, 1, 0) layout.addWidget(inputLabel, 1, 1) layout.addWidget(self._changeEncoding, 2, 0) layout.addWidget(self._outputEncoding, 3, 0) layout.addWidget(outputLabel, 3, 1) groupbox.setLayout(layout) return groupbox def _createFormatBox(self): groupbox = QGroupBox(_("Subtitle format")) layout = QGridLayout() displayedFormats = list(self._formats.keys()) displayedFormats.sort() self._outputFormat = QComboBox(self) self._outputFormat.addItems(displayedFormats) formatLabel = QLabel(_("Output format")) layout.addWidget(self._outputFormat, 0, 0) layout.addWidget(formatLabel, 0, 1) groupbox.setLayout(layout) return groupbox def _createButtons(self): widget = QWidget(self) layout = QHBoxLayout() self._openButton = QPushButton(_("Open")) self._saveButton = QPushButton(_("Save")) self._closeButton = QPushButton(_("Close")) layout.addWidget(self._openButton) layout.addWidget(self._saveButton) layout.addWidget(self._closeButton) widget.setLayout(layout) return widget def _createSubtitleProperties(self): subProperties = SubtitleProperties(list(self._formats.values())) subProperties.autoFps = self._autoFps.isChecked() subProperties.fps = self._fps.currentText() subProperties.autoInputEncoding = self._autoEncoding.isChecked() subProperties.changeEncoding = self._changeEncoding.isChecked() subProperties.inputEncoding = self._inputEncoding.currentText() subProperties.outputEncoding = self._outputEncoding.currentText() subProperties.outputFormat = self._formats.get(self._outputFormat.currentText()) return subProperties def changeProperties(self, subProperties): self._autoFps.setChecked(subProperties.autoFps) self._fps.setEditText(str(subProperties.fps)) self._autoEncoding.setChecked(subProperties.autoInputEncoding) self._changeEncoding.setChecked(subProperties.changeEncoding) self._inputEncoding.setCurrentIndex( self._inputEncoding.findText(subProperties.inputEncoding)) self._outputEncoding.setCurrentIndex( self._outputEncoding.findText(subProperties.outputEncoding)) if self._formats.get(subProperties.outputFormat.NAME) is subProperties.outputFormat: self._outputFormat.setCurrentIndex( self._outputFormat.findText(subProperties.outputFormat.NAME)) else: self.close() raise RuntimeError(_("Subtitle format (%s) doesn't match any of known formats!") % subProperties.outputFormat.NAME) def saveProperties(self): subProperties = None try: subProperties = self._createSubtitleProperties() except Exception as e: dialog = QMessageBox(self) dialog.setIcon(QMessageBox.Critical) dialog.setWindowTitle(_("Incorrect value")) dialog.setText(_("Could not save SPF file because of incorrect parameters.")); dialog.setDetailedText(str(e)); dialog.exec() return fileDialog = FileDialog( parent = self, caption = _('Save Subtitle Properties'), directory = self._settings.getPropertyFilesPath() ) fileDialog.setAcceptMode(QFileDialog.AcceptSave) fileDialog.setFileMode(QFileDialog.AnyFile) if fileDialog.exec(): filename = fileDialog.selectedFiles()[0] if not filename.endswith(".spf"): filename = "%s%s" % (filename, ".spf") self._settings.setPropertyFilesPath(os.path.dirname(filename)) subProperties.save(filename) self._settings.addPropertyFile(filename) self.close() def openProperties(self): fileDialog = FileDialog( parent = self, caption = _("Open Subtitle Properties"), directory = self._settings.getPropertyFilesPath(), filter = _("Subtitle Properties (*.spf);;All files (*)") ) fileDialog.setFileMode(QFileDialog.ExistingFile) if fileDialog.exec(): filename = fileDialog.selectedFiles()[0] self._settings.setPropertyFilesPath(os.path.dirname(filename)) subProperties = SubtitleProperties(list(self._formats.values()), filename) self.changeProperties(subProperties)
class NewGameWidget(Tab): def __init__(self, parent=None): super(NewGameWidget, self).__init__(parent) self.parent = parent self.initUI() def initUI(self): # Setup Layouts self.widgetLayout = QHBoxLayout(self) self.leftColumnLayout = QVBoxLayout() self.rightColumnLayout = QVBoxLayout() self.widgetLayout.addLayout(self.leftColumnLayout) self.widgetLayout.addLayout(self.rightColumnLayout) self.gameStatsBox = None # Players GroupBox self.playersGroupBox = QGroupBox(self) self.rightColumnLayout.addWidget(self.playersGroupBox) self.widgetLayout.setStretchFactor(self.rightColumnLayout, 1) self.populatePlayersGroupBox() # Game GroupBox self.gameGroupBox = QGroupBox(self) self.leftColumnLayout.addWidget(self.gameGroupBox) self.widgetLayout.setStretchFactor(self.leftColumnLayout, 3) self.populateGamesGroupBox() # self.retranslateUI() def retranslateUI(self): self.gameGroupBox.setTitle( i18n("NewGameWidget", "Games")) self.updateGameInfo() self.playersGroupBox.setTitle( i18n("NewGameWidget", "Players")) self.availablePlayersGroup.setTitle( i18n("NewGameWidget", "Available Players")) self.newPlayerButton.setText( i18n("NewGameWidget", "New Player")) self.inGameGroup.setTitle(i18n( "NewGameWidget", "Selected Players")) self.startGameButton.setText( i18n("NewGameWidget", "Play!")) self.resumeGroup.retranslateUI() self.gameStatsBox.retranslateUI() def populateGamesGroupBox(self): self.gameGroupBoxLayout = QVBoxLayout(self.gameGroupBox) self.gameComboBox = QComboBox(self.gameGroupBox) self.gameGroupBoxLayout.addWidget(self.gameComboBox) self.gameDescriptionLabel = QLabel(self.gameGroupBox) self.resumeGroup = ResumeBox(self.parent) self.resumeGroup.restartRequested.connect(self.restartGame) # self.gameRulesBrowser = QTextBrowser(self.gameGroupBox) self.gameGroupBoxLayout.addWidget(self.gameDescriptionLabel) self.gameGroupBoxLayout.addWidget(self.resumeGroup) # self.gameGroupBoxLayout.addWidget(self.gameRulesBrowser) # self.gameGroupBoxLayout.addStretch() self.games = db.getAvailableGames() for game in sorted(self.games.keys()): self.gameComboBox.addItem(game) lastgame = db.getLastGame() if lastgame: self.gameComboBox.setCurrentIndex( self.gameComboBox.findText(lastgame)) self.gameStatsBox = None # self.updateGameInfo() self.gameComboBox.currentIndexChanged.connect(self.updateGameInfo) def updateGameInfo(self, foo=0): game = str(self.gameComboBox.currentText()) description = "2 - {} {}\n\n{}".format( self.games[game]['maxPlayers'], i18n("NewGameWidget", 'players'), self.games[game]['description']) self.gameDescriptionLabel.setText(description) # self.gameRulesBrowser.setText("{}".format(self.games[game]['rules'])) # self.gameStatsBox.update(game) if self.gameStatsBox is not None: self.gameGroupBoxLayout.removeWidget(self.gameStatsBox) # print("UGI deleting") self.gameStatsBox.deleteLater() self.gameStatsBox = QSFactory.createQS(game, None, self) self.gameGroupBoxLayout.addWidget(self.gameStatsBox) self.updateStats() self.resumeGroup.changeGame(game) def updateStats(self): if self.gameStatsBox: try: self.gameStatsBox.update(self.gameComboBox.currentText( ), self.playersInGameList.model().retrievePlayers()) except TypeError: # Should not happen, but silently ignore pass def populatePlayersGroupBox(self): self.playersGroupBoxLayout = QVBoxLayout( self.playersGroupBox) # Start button self.startGameButton = QPushButton(self) self.startGameButton.clicked.connect(self.createNewGame) self.playersGroupBoxLayout.addWidget(self.startGameButton) self.inGameGroup = QGroupBox(self) self.playersGroupBoxLayout.addWidget(self.inGameGroup) self.inGameGroupLayout = QVBoxLayout(self.inGameGroup) self.playersInGameList = PlayerList(None, self.inGameGroup) self.inGameGroup.setMaximumHeight(280) self.inGameGroupLayout.addWidget(self.playersInGameList) self.playersButtonsLayout = QHBoxLayout() self.playersGroupBoxLayout.addLayout(self.playersButtonsLayout) self.newPlayerButton = QPushButton(self.playersGroupBox) self.newPlayerButton.clicked.connect(self.createNewPlayer) self.playersButtonsLayout.addWidget(self.newPlayerButton) self.availablePlayersGroup = QGroupBox(self) self.playersGroupBoxLayout.addWidget(self.availablePlayersGroup) self.availablePlayersGroupLayout = QVBoxLayout( self.availablePlayersGroup) self.playersAvailableList = PlayerList(None, self.playersGroupBox) self.availablePlayersGroupLayout.addWidget(self.playersAvailableList) # self.availablePlayersGroupLayout.addStretch() self.playersAvailableList.doubleclickeditem.connect( self.playersInGameList.addItem) self.playersInGameList.doubleclickeditem.connect( self.playersAvailableList.addItem) self.playersInGameList.changed.connect(self.updateStats) for p in db.getPlayers(): if p['favourite']: self.playersInGameList.addItem(p['nick']) else: self.playersAvailableList.addItem(p['nick']) def createNewGame(self): game = str(self.gameComboBox.currentText()) maxPlayers = self.games[game]['maxPlayers'] players = self.playersInGameList.model().retrievePlayers() tit = i18n("NewGameWidget", "New Match") if len(players) < 2: msg = i18n( "NewGameWidget", "At least 2 players are needed to play") QMessageBox.warning(self, tit, msg) elif len(players) > maxPlayers: msg = i18n("NewGameWidget", 'The maximum number of players is') QMessageBox.warning(self, tit, "{} {}".format(msg, maxPlayers)) else: matchTab = GameWidgetFactory.createGameWidget( game, players, self.parent) if matchTab: matchTab.closeRequested.connect(self.parent.removeTab) matchTab.restartRequested.connect(self.restartGame) self.parent.newTab(matchTab, game) else: QMessageBox.warning(self, tit, i18n("NewGameWidget", "Widget not implemented")) return def restartGame(self, gamewidget): players = gamewidget.players game = gamewidget.game self.parent.removeTab(gamewidget) matchTab = GameWidgetFactory.createGameWidget( game, players, self.parent) if matchTab: matchTab.closeRequested.connect(self.parent.removeTab) matchTab.restartRequested.connect(self.restartGame) self.parent.newTab(matchTab, game) else: QMessageBox.warning(self, tit, i18n("NewGameWidget", "Widget not implemented")) return def createNewPlayer(self): npd = NewPlayerDialog(self) npd.addedNewPlayer.connect(self.addPlayer) npd.exec_() def addPlayer(self, player): player = str(player) self.playersAvailableList.model().addPlayer(player) def showEvent(self, event): if (hasattr(self, 'gameStatsBox') and hasattr(self, 'gameComboBox') and self.gameComboBox.currentText()): self.gameStatsBox.update(self.gameComboBox.currentText()) self.resumeGroup.changeGame(self.gameComboBox.currentText()) return QWidget.showEvent(self, event)
class SourceExport(preferences.Group): def __init__(self, page): super(SourceExport, self).__init__(page) layout = QGridLayout(spacing=1) self.setLayout(layout) self.numberLines = QCheckBox(toggled=self.changed) self.inlineStyleCopy = QCheckBox(toggled=self.changed) self.copyHtmlAsPlainText = QCheckBox(toggled=self.changed) self.inlineStyleExport = QCheckBox(toggled=self.changed) self.copyDocumentBodyOnly = QCheckBox(toggled=self.changed) self.wrapperTag = QLabel() self.wrapTagSelector = QComboBox() self.wrapTagSelector.currentIndexChanged.connect(page.changed) self.wrapperAttribute = QLabel() self.wrapAttribSelector = QComboBox() self.wrapAttribSelector.currentIndexChanged.connect(page.changed) self.wrapAttribNameLabel = QLabel() self.wrapAttribName = QLineEdit() self.wrapAttribName.textEdited.connect(page.changed) self.wrapperTag.setBuddy(self.wrapTagSelector) self.wrapperAttribute.setBuddy(self.wrapAttribSelector) self.wrapAttribNameLabel.setBuddy(self.wrapAttribName) layout.addWidget(self.copyHtmlAsPlainText, 0, 0, 1, 2) layout.addWidget(self.copyDocumentBodyOnly, 1, 0, 1, 2) layout.addWidget(self.inlineStyleCopy, 2, 0, 1, 2) layout.addWidget(self.inlineStyleExport, 3, 0, 1, 2) layout.addWidget(self.numberLines, 4, 0, 1, 2) layout.addWidget(self.wrapperTag, 5, 0) layout.addWidget(self.wrapTagSelector, 5, 1) layout.addWidget(self.wrapperAttribute, 6, 0) layout.addWidget(self.wrapAttribSelector, 6, 1) layout.addWidget(self.wrapAttribNameLabel, 7, 0) layout.addWidget(self.wrapAttribName, 7, 1) self.wrapTagSelector.addItem("pre") self.wrapTagSelector.addItem("code") self.wrapTagSelector.addItem("div") self.wrapAttribSelector.addItem("id") self.wrapAttribSelector.addItem("class") app.translateUI(self) def translateUI(self): self.setTitle(_("Source Export Preferences")) self.numberLines.setText(_("Show line numbers")) self.numberLines.setToolTip('<qt>' + _( "If enabled, line numbers are shown in exported HTML or printed " "source.")) self.inlineStyleCopy.setText(_("Use inline style when copying colored HTML")) self.inlineStyleCopy.setToolTip('<qt>' + _( "If enabled, inline style attributes are used when copying " "colored HTML to the clipboard. " "Otherwise, a CSS stylesheet is embedded.")) self.inlineStyleExport.setText(_("Use inline style when exporting colored HTML")) self.inlineStyleExport.setToolTip('<qt>' + _( "If enabled, inline style attributes are used when exporting " "colored HTML to a file. " "Otherwise, a CSS stylesheet is embedded.")) self.copyHtmlAsPlainText.setText(_("Copy HTML as plain text")) self.copyHtmlAsPlainText.setToolTip('<qt>' + _( "If enabled, HTML is copied to the clipboard as plain text. " "Use this when you want to type HTML formatted code in a " "plain text editing environment.")) self.copyDocumentBodyOnly.setText(_("Copy document body only")) self.copyDocumentBodyOnly.setToolTip('<qt>' + _( "If enabled, only the HTML contents, wrapped in a single tag, will be " "copied to the clipboard instead of a full HTML document with a " "header section. " "May be used in conjunction with the plain text option, with the " "inline style option turned off, to copy highlighted code in a " "text editor when an external style sheet is already available.")) self.wrapperTag.setText(_("Tag to wrap around source:" + " ")) self.wrapperTag.setToolTip('<qt>' + _( "Choose what tag the colored HTML will be wrapped into.")) self.wrapperAttribute.setText(_("Attribute type of wrapper:" + " ")) self.wrapperAttribute.setToolTip('<qt>' + _( "Choose whether the wrapper tag should be of type 'id' or 'class'")) self.wrapAttribNameLabel.setText(_("Name of attribute:" + " ")) self.wrapAttribNameLabel.setToolTip('<qt>' + _( "Arbitrary name for the type attribute. " + "This must match the CSS stylesheet if using external CSS.")) def loadSettings(self): s = QSettings() s.beginGroup("source_export") self.numberLines.setChecked(s.value("number_lines", False, bool)) self.inlineStyleCopy.setChecked(s.value("inline_copy", True, bool)) self.inlineStyleExport.setChecked(s.value("inline_export", False, bool)) self.copyHtmlAsPlainText.setChecked(s.value("copy_html_as_plain_text", False, bool)) self.copyDocumentBodyOnly.setChecked(s.value("copy_document_body_only", False, bool)) self.wrapTagSelector.setCurrentIndex( self.wrapTagSelector.findText(s.value("wrap_tag", "pre", str))) self.wrapAttribSelector.setCurrentIndex( self.wrapAttribSelector.findText(s.value("wrap_attrib", "id", str))) self.wrapAttribName.setText(s.value("wrap_attrib_name", "document", str)) def saveSettings(self): s = QSettings() s.beginGroup("source_export") s.setValue("number_lines", self.numberLines.isChecked()) s.setValue("inline_copy", self.inlineStyleCopy.isChecked()) s.setValue("inline_export", self.inlineStyleExport.isChecked()) s.setValue("copy_html_as_plain_text", self.copyHtmlAsPlainText.isChecked()) s.setValue("copy_document_body_only", self.copyDocumentBodyOnly.isChecked()) s.setValue("wrap_tag", self.wrapTagSelector.currentText()) s.setValue("wrap_attrib", self.wrapAttribSelector.currentText()) s.setValue("wrap_attrib_name", self.wrapAttribName.text())
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() centralWidget = QWidget() fontLabel = QLabel("Font:") self.fontCombo = QFontComboBox() sizeLabel = QLabel("Size:") self.sizeCombo = QComboBox() styleLabel = QLabel("Style:") self.styleCombo = QComboBox() fontMergingLabel = QLabel("Automatic Font Merging:") self.fontMerging = QCheckBox() self.fontMerging.setChecked(True) self.scrollArea = QScrollArea() self.characterWidget = CharacterWidget() self.scrollArea.setWidget(self.characterWidget) self.findStyles(self.fontCombo.currentFont()) self.findSizes(self.fontCombo.currentFont()) self.lineEdit = QLineEdit() clipboardButton = QPushButton("&To clipboard") self.clipboard = QApplication.clipboard() self.fontCombo.currentFontChanged.connect(self.findStyles) self.fontCombo.activated[str].connect(self.characterWidget.updateFont) self.styleCombo.activated[str].connect(self.characterWidget.updateStyle) self.sizeCombo.currentIndexChanged[str].connect(self.characterWidget.updateSize) self.characterWidget.characterSelected.connect(self.insertCharacter) clipboardButton.clicked.connect(self.updateClipboard) controlsLayout = QHBoxLayout() controlsLayout.addWidget(fontLabel) controlsLayout.addWidget(self.fontCombo, 1) controlsLayout.addWidget(sizeLabel) controlsLayout.addWidget(self.sizeCombo, 1) controlsLayout.addWidget(styleLabel) controlsLayout.addWidget(self.styleCombo, 1) controlsLayout.addWidget(fontMergingLabel) controlsLayout.addWidget(self.fontMerging, 1) controlsLayout.addStretch(1) lineLayout = QHBoxLayout() lineLayout.addWidget(self.lineEdit, 1) lineLayout.addSpacing(12) lineLayout.addWidget(clipboardButton) centralLayout = QVBoxLayout() centralLayout.addLayout(controlsLayout) centralLayout.addWidget(self.scrollArea, 1) centralLayout.addSpacing(4) centralLayout.addLayout(lineLayout) centralWidget.setLayout(centralLayout) self.setCentralWidget(centralWidget) self.setWindowTitle("Character Map") def findStyles(self, font): fontDatabase = QFontDatabase() currentItem = self.styleCombo.currentText() self.styleCombo.clear() for style in fontDatabase.styles(font.family()): self.styleCombo.addItem(style) styleIndex = self.styleCombo.findText(currentItem) if styleIndex == -1: self.styleCombo.setCurrentIndex(0) else: self.styleCombo.setCurrentIndex(styleIndex) def findSizes(self, font): fontDatabase = QFontDatabase() currentSize = self.sizeCombo.currentText() self.sizeCombo.blockSignals(True) self.sizeCombo.clear() if fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font)): for size in QFontDatabase.standardSizes(): self.sizeCombo.addItem(str(size)) self.sizeCombo.setEditable(True) else: for size in fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font)): self.sizeCombo.addItem(str(size)) self.sizeCombo.setEditable(False) self.sizeCombo.blockSignals(False) sizeIndex = self.sizeCombo.findText(currentSize) if sizeIndex == -1: self.sizeCombo.setCurrentIndex(max(0, self.sizeCombo.count() / 3)) else: self.sizeCombo.setCurrentIndex(sizeIndex) def insertCharacter(self, character): self.lineEdit.insert(character) def updateClipboard(self): self.clipboard.setText(self.lineEdit.text(), QClipboard.Clipboard) self.clipboard.setText(self.lineEdit.text(), QClipboard.Selection)
def updateLayout(self): self.updating = True for i in reversed(range(self.variableLayout.count())): if i > 1: self.variableLayout.itemAt(i).widget().deleteLater() for i, variable in enumerate(self.variables): self.currentVariable = i Cat1 = QComboBox() Cat1.addItems(['material', 'stack']) Cat1.setCurrentIndex(variable[0]) Cat1.currentIndexChanged.connect(self.cat1Changed) Cat2 = QComboBox() if variable[0] == 0: Cat2.addItems(self.layers) else: Cat2.addItems(['excitation']) Cat2.currentIndexChanged.connect(self.cat2Changed) idx = Cat2.findText(variable[1]) if idx >= 0: Cat2.setCurrentIndex(idx) else: Cat2.setCurrentIndex(0) self.variables[i][1] = Cat2.currentText() Cat3 = QComboBox() if variable[0] == 0: Cat3.addItems(self.materialParameters) else: Cat3.addItems(self.stackParameters) Cat3.currentIndexChanged.connect(self.cat3Changed) idx = Cat3.findText(variable[2]) if idx >= 0: Cat3.setCurrentIndex(idx) else: Cat3.setCurrentIndex(0) self.variables[i][2] = Cat3.currentText() startSB = QDoubleSpinBox() stepSB = QDoubleSpinBox() stopSB = QDoubleSpinBox() if variable[2] == 'thickness' or variable[2] == 'roughness': startSB.setRange(1.0, 9998.0) startSB.setSingleStep(1) stepSB.setRange(1.0, 9998.0) stepSB.setSingleStep(1.0) stopSB.setRange(2.0, 9999.0) stopSB.setSingleStep(1.0) elif variable[2] == 'constant n' or variable[2] == 'constant k': startSB.setRange(0.0, 20.0) startSB.setSingleStep(0.1) stepSB.setRange(0.01, 1.0) stepSB.setSingleStep(0.01) stopSB.setRange(0.01, 20.0) stopSB.setSingleStep(0.01) elif variable[2] == 'Haze R' or variable[2] == 'Haze T': startSB.setRange(0.0, 1.0) startSB.setSingleStep(1) stepSB.setRange(0.01, 1.0) stepSB.setSingleStep(1.0) stopSB.setRange(0.01, 1.0) stopSB.setSingleStep(0.01) elif variable[2] == 'angle of incident': startSB.setRange(0.0, 89.0) startSB.setSingleStep(1) stepSB.setRange(1.0, 90.0) stepSB.setSingleStep(1) stopSB.setRange(2.0, 90.0) stopSB.setSingleStep(1.0) else: startSB.setRange(0.0, 999999) startSB.setSingleStep(1) stepSB.setRange(1.0, 999999) stepSB.setSingleStep(1) stopSB.setRange(0.000001, 999999) stopSB.setSingleStep(1.0) startSB.setValue(variable[3][0]) stepSB.setValue(variable[3][1]) stopSB.setValue(variable[3][2]) startSB.valueChanged.connect(self.startSBChanged) stepSB.valueChanged.connect(self.stepSBChanged) stopSB.valueChanged.connect(self.stopSBChanged) stopSB.setValue(variable[3][2]) self.variableLayout.addWidget(Cat1, i+1, 0) self.variableLayout.addWidget(Cat2, i+1, 1) self.variableLayout.addWidget(Cat3, i+1, 2) self.variableLayout.addWidget(startSB, i+1, 3) self.variableLayout.addWidget(stepSB, i+1, 4) self.variableLayout.addWidget(stopSB, i+1, 5) self.updating = False
class AudioVideoTab(QWidget): def __init__(self, parent): super(AudioVideoTab, self).__init__(parent) self.parent = parent self.name = 'AudioVideo' self.defaultStr = self.tr('Default') self.DisableStream = self.tr('Disable') self.formats = config.video_formats frequency_values = [self.defaultStr] + config.video_frequency_values bitrate_values = [self.defaultStr] + config.video_bitrate_values rotation_options = [ self.tr('None'), '90 ' + self.tr('clockwise'), '90 ' + self.tr('clockwise') + ' + ' + self.tr('vertical flip'), '90 ' + self.tr('counter clockwise'), '90 ' + self.tr('counter clockwise') + ' + ' + self.tr('vertical flip'), '180', self.tr('horizontal flip'), self.tr('vertical flip') ] digits_validator = QRegExpValidator(QRegExp(r'[1-9]\d*'), self) digits_validator_wzero = QRegExpValidator(QRegExp(r'\d*'), self) digits_validator_minus = QRegExpValidator(QRegExp(r'(-1|[1-9]\d*)'), self) time_validator = QRegExpValidator( QRegExp(r'\d{1,2}:\d{1,2}:\d{1,2}\.\d+'), self) converttoQL = QLabel(self.tr('Convert to:')) self.extQCB = QComboBox() self.extQCB.setMinimumWidth(100) vidcodecQL = QLabel('Video codec:') self.vidcodecQCB = QComboBox() self.vidcodecQCB.setMinimumWidth(110) audcodecQL = QLabel('Audio codec:') self.audcodecQCB = QComboBox() self.audcodecQCB.setMinimumWidth(110) hlayout1 = utils.add_to_layout( 'h', converttoQL, self.extQCB, QSpacerItem(180, 20), vidcodecQL, self.vidcodecQCB, audcodecQL, self.audcodecQCB) commandQL = QLabel(self.tr('Command:')) self.commandQLE = QLineEdit() self.presetQPB = QPushButton(self.tr('Preset')) self.defaultQPB = QPushButton(self.defaultStr) hlayout2 = utils.add_to_layout( 'h', commandQL, self.commandQLE, self.presetQPB, self.defaultQPB) sizeQL = QLabel(self.tr('Video Size:')) aspectQL = QLabel(self.tr('Aspect:')) frameQL = QLabel(self.tr('Frame Rate (fps):')) bitrateQL = QLabel(self.tr('Video Bitrate (kbps):')) self.widthQLE = utils.create_LineEdit( (70, 16777215), digits_validator_minus, 4) self.heightQLE = utils.create_LineEdit( (70, 16777215), digits_validator_minus, 4) label = QLabel('<html><p align="center">x</p></html>') layout1 = utils.add_to_layout('h', self.widthQLE, label,self.heightQLE) self.aspect1QLE = utils.create_LineEdit( (50, 16777215), digits_validator, 2) self.aspect2QLE = utils.create_LineEdit( (50, 16777215), digits_validator, 2) label = QLabel('<html><p align="center">:</p></html>') layout2 = utils.add_to_layout( 'h', self.aspect1QLE, label, self.aspect2QLE) self.frameQLE = utils.create_LineEdit( (120, 16777215), digits_validator, 4) self.bitrateQLE = utils.create_LineEdit( (130, 16777215), digits_validator, 6) labels = [sizeQL, aspectQL, frameQL, bitrateQL] widgets = [layout1, layout2, self.frameQLE, self.bitrateQLE] self.preserveaspectQChB = QCheckBox(self.tr("Preserve aspect ratio")) self.preservesizeQChB = QCheckBox(self.tr("Preserve video size")) preserve_layout = utils.add_to_layout( 'v', self.preserveaspectQChB, self.preservesizeQChB) videosettings_layout = QHBoxLayout() for a, b in zip(labels, widgets): a.setText('<html><p align="center">{0}</p></html>'.format(a.text())) layout = utils.add_to_layout('v', a, b) videosettings_layout.addLayout(layout) if a == aspectQL: # add vidaspectCB in layout after aspectQL videosettings_layout.addLayout(preserve_layout) freqQL = QLabel(self.tr('Frequency (Hz):')) chanQL = QLabel(self.tr('Audio Channels:')) bitrateQL = QLabel(self.tr('Audio Bitrate (kbps):')) threadsQL = QLabel(self.tr('Threads:')) self.freqQCB = QComboBox() self.freqQCB.addItems(frequency_values) self.chan1QRB = QRadioButton('1') self.chan1QRB.setMaximumSize(QSize(51, 16777215)) self.chan2QRB = QRadioButton('2') self.chan2QRB.setMaximumSize(QSize(51, 16777215)) self.group = QButtonGroup() self.group.addButton(self.chan1QRB) self.group.addButton(self.chan2QRB) spcr1 = QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Minimum) spcr2 = QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Minimum) chanlayout = utils.add_to_layout( 'h', spcr1, self.chan1QRB, self.chan2QRB, spcr2) self.audbitrateQCB = QComboBox() self.audbitrateQCB.addItems(bitrate_values) self.threadsQLE = utils.create_LineEdit( (50, 16777215), digits_validator_wzero, 1) labels = [freqQL, bitrateQL, chanQL, threadsQL] widgets = [self.freqQCB, self.audbitrateQCB, chanlayout,self.threadsQLE] audiosettings_layout = QHBoxLayout() for a, b in zip(labels, widgets): a.setText('<html><p align="center">{0}</p></html>'.format(a.text())) layout = utils.add_to_layout('v', a, b) audiosettings_layout.addLayout(layout) time_format = " (hh:mm:ss):" beginQL = QLabel(self.tr("Split file. Begin time") + time_format) self.beginQLE = utils.create_LineEdit(None, time_validator, None) durationQL = QLabel(self.tr("Duration") + time_format) self.durationQLE = utils.create_LineEdit(None, time_validator, None) hlayout4 = utils.add_to_layout( 'h', beginQL, self.beginQLE, durationQL, self.durationQLE) embedQL = QLabel(self.tr("Embed subtitle:")) self.embedQLE = QLineEdit() self.embedQTB = QToolButton() self.embedQTB.setText("...") rotateQL = QLabel(self.tr("Rotate:")) self.rotateQCB = QComboBox() self.rotateQCB.addItems(rotation_options) hlayout5 = utils.add_to_layout( 'h', rotateQL, self.rotateQCB, embedQL, self.embedQLE, self.embedQTB) hidden_layout = utils.add_to_layout( 'v', videosettings_layout, audiosettings_layout, hlayout4, hlayout5) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.moreQPB = QPushButton(QApplication.translate('Tab', 'More')) self.moreQPB.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.moreQPB.setCheckable(True) hlayout3 = utils.add_to_layout('h', line, self.moreQPB) self.frame = QFrame() self.frame.setLayout(hidden_layout) self.frame.hide() final_layout = utils.add_to_layout( 'v', hlayout1, hlayout2, hlayout3, self.frame) self.setLayout(final_layout) self.presetQPB.clicked.connect(self.choose_preset) self.defaultQPB.clicked.connect(self.set_default_command) self.embedQTB.clicked.connect(self.open_subtitle_file) self.moreQPB.toggled.connect(self.frame.setVisible) self.moreQPB.toggled.connect( lambda: QTimer.singleShot(100, self.resize_parent)) self.widthQLE.textChanged.connect(self.command_update_size) self.heightQLE.textChanged.connect(self.command_update_size) self.aspect1QLE.textChanged.connect(self.command_update_aspect) self.aspect2QLE.textChanged.connect(self.command_update_aspect) self.frameQLE.textChanged.connect(self.command_update_frames) self.bitrateQLE.textChanged.connect(self.command_update_vidbitrate) self.threadsQLE.textChanged.connect(self.command_update_threads) self.beginQLE.textChanged.connect(self.command_update_begin_time) self.durationQLE.textChanged.connect(self.command_update_duration) self.embedQLE.textChanged.connect(self.command_update_subtitles) self.vidcodecQCB.currentIndexChanged.connect(self.command_update_vcodec) self.audcodecQCB.currentIndexChanged.connect(self.command_update_acodec) self.freqQCB.currentIndexChanged.connect(self.command_update_frequency) self.rotateQCB.currentIndexChanged.connect(self.command_update_rotation) self.audbitrateQCB.currentIndexChanged.connect( self.command_update_audbitrate) self.chan1QRB.clicked.connect( lambda: self.command_update_channels('1')) self.chan2QRB.clicked.connect( lambda: self.command_update_channels('2')) self.preserveaspectQChB.toggled.connect( self.command_update_preserve_aspect) self.preservesizeQChB.toggled.connect( self.command_update_preserve_size) def resize_parent(self): """Give MainWindow its default size.""" self.parent.setMinimumSize(self.parent.sizeHint()) self.parent.resize(self.parent.sizeHint()) def clear(self): """Clear all values of graphical widgets.""" lines = [ self.commandQLE, self.widthQLE, self.heightQLE, self.aspect1QLE, self.aspect2QLE, self.frameQLE, self.bitrateQLE, self.threadsQLE, self.beginQLE, self.embedQLE, self.durationQLE ] for i in lines: i.clear() self.vidcodecQCB.setCurrentIndex(0) self.audcodecQCB.setCurrentIndex(0) self.freqQCB.setCurrentIndex(0) self.audbitrateQCB.setCurrentIndex(0) self.rotateQCB.setCurrentIndex(0) self.preserveaspectQChB.setChecked(False) self.preservesizeQChB.setChecked(False) self.group.setExclusive(False) self.chan1QRB.setChecked(False) self.chan2QRB.setChecked(False) self.group.setExclusive(True) # setExclusive(False) in order to be able to uncheck checkboxes and # then setExclusive(True) so only one radio button can be set def fill_video_comboboxes(self, vcodecs, acodecs, extraformats): self.vidcodecQCB.currentIndexChanged.disconnect() self.audcodecQCB.currentIndexChanged.disconnect() self.vidcodecQCB.clear() self.audcodecQCB.clear() self.extQCB.clear() self.vidcodecQCB.addItems([self.defaultStr, self.DisableStream] + vcodecs) self.audcodecQCB.addItems([self.defaultStr, self.DisableStream] + acodecs) self.extQCB.addItems(sorted(self.formats + extraformats)) self.vidcodecQCB.currentIndexChanged.connect(self.command_update_vcodec) self.audcodecQCB.currentIndexChanged.connect(self.command_update_acodec) def ok_to_continue(self): """ Check if everything is ok with audiovideotab to continue conversion. Returns boolean. """ if not self.parent.ffmpeg_path: QMessageBox.warning(self, 'FF Multi Converter - ' + self.tr( 'Error!'), self.tr('FFmpeg is not installed!')) return False return True def open_subtitle_file(self): fname = QFileDialog.getOpenFileName( self, 'FF Multi Converter - ' + self.tr('Choose File'), config.home, 'Subtitles (*.srt *.sub *.ssa *.ass)' )[0] if fname: self.embedQLE.setText(fname) def set_default_command(self): """Set the default value to self.commandQLE.""" self.clear() self.commandQLE.setText(self.parent.default_command) def choose_preset(self): """ Open the presets dialog and update self.commandQLE, and self.extQCB and with the appropriate values. """ dialog = presets_dlgs.ShowPresets(choose=True) if dialog.exec_() and dialog.the_command is not None: self.clear() self.commandQLE.setText(dialog.the_command) self.commandQLE.home(False) find = self.extQCB.findText(dialog.the_extension) if find >= 0: self.extQCB.setCurrentIndex(find) def command_update_size(self): command = self.commandQLE.text() text1 = self.widthQLE.text() text2 = self.heightQLE.text() if not (text1 == '-1' or text2 == '-1'): self.preserveaspectQChB.setChecked(False) if (text1 or text2) and not (text1 and text2) or (text1 == '-' or text2 == '-'): return regex = r'(\s+|^)-s(:v){0,1}\s+\d+x\d+(\s+|$)' if re.search(regex, command): command = re.sub(regex, '', command) regex = r'(,*\s*){0,1}(scale=-?\d+:-?\d+)(\s*,*\s*){0,1}' _filter = "scale={0}:{1}".format(text1, text2) if text1 and text2 else '' self.commandQLE.setText(utils.update_cmdline_text( command, _filter, regex, bool(text1 and text2), 0, 2)) def command_update_preserve_size(self): checked = self.preservesizeQChB.isChecked() self.widthQLE.setEnabled(not checked) self.heightQLE.setEnabled(not checked) if checked: self.widthQLE.clear() self.heightQLE.clear() # command_update_size() is triggered here command = self.commandQLE.text() regex = r'(\s+|^)-s\s+\d+x\d+(\s+|$)' command = re.sub(' +', ' ', re.sub(regex, ' ', command)).strip() self.commandQLE.setText(command) def command_update_aspect(self): command = self.commandQLE.text() text1 = self.aspect1QLE.text() text2 = self.aspect2QLE.text() if (text1 or text2) and not (text1 and text2): return regex = r'(\s+|^)-aspect\s+\d+:\d+(\s+|$)' s = ' -aspect {0}:{1} '.format(text1, text2) if text1 and text2 else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_preserve_aspect(self): command = self.commandQLE.text() checked = self.preserveaspectQChB.isChecked() self.aspect1QLE.setEnabled(not checked) self.aspect2QLE.setEnabled(not checked) if checked: self.aspect1QLE.clear() self.aspect2QLE.clear() # self.command_update_aspect() is triggered here regex = r'(,*\s*){0,1}(scale=(-?\d+):(-?\d+))(\s*,*\s*){0,1}' search = re.search(regex, command) if search: width = search.groups()[2] height = search.groups()[3] if not (width == '-1' or height == '-1'): s = "scale=-1:{0}".format(height) command = re.sub(regex, r'\1{0}\5'.format(s), command) self.widthQLE.setText('-1') self.heightQLE.setText(height) regex = r'(\s+|^)-aspect\s+\d+:\d+(\s+|$)' command = re.sub(' +', ' ', re.sub(regex, ' ', command)).strip() self.commandQLE.setText(command) def command_update_frames(self): command = self.commandQLE.text() text = self.frameQLE.text() regex = r'(\s+|^)-r\s+\d+(\s+|$)' s = ' -r {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_vidbitrate(self): command = self.commandQLE.text() text = self.bitrateQLE.text() regex = r'(\s+|^)-b(:v){0,1}\s+\d+[kKmM](\s+|$)' s = ' -b:v {0}k '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub('-sameq', '', command) command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_frequency(self): command = self.commandQLE.text() text = self.freqQCB.currentText() regex = r'(\s+|^)-ar\s+\d+(\s+|$)' s = ' -ar {0} '.format(text) if self.freqQCB.currentIndex() != 0 else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_audbitrate(self): command = self.commandQLE.text() text = self.audbitrateQCB.currentText() regex = r'(\s+|^)-(ab|b:a)\s+\d+[kKmM](\s+|$)' if self.audbitrateQCB.currentIndex() != 0: s = ' -b:a {0}k '.format(text) else: s = ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_channels(self, channel): command = self.commandQLE.text() regex = r'(\s+|^)-ac\s+\d+(\s+|$)' s = ' -ac {0} '.format(channel) if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_threads(self): command = self.commandQLE.text() text = self.threadsQLE.text() regex = r'(\s+|^)-threads\s+\d+(\s+|$)' s = ' -threads {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_begin_time(self): command = self.commandQLE.text() text = self.beginQLE.text() regex = r'(\s+|^)-ss\s+\S+(\s+|$)' s = ' -ss {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_duration(self): command = self.commandQLE.text() text = self.durationQLE.text() regex = r'(\s+|^)-t\s+\S+(\s+|$)' s = ' -t {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_vcodec(self): command = self.commandQLE.text() text = self.vidcodecQCB.currentText() regex = r'(\s+|^)-(vcodec|c:v)\s+\S+(\s+|$)' regex_vn = r'(\s+|^)-vn(\s+|$)' if self.vidcodecQCB.currentIndex() == 1: s = ' -vn '.format(text) elif self.vidcodecQCB.currentIndex() == 0: s = ' ' else: s = ' -vcodec {0} '.format(text) if re.search(regex, command): command = re.sub(regex, s, command) elif re.search(regex_vn, command): command = re.sub(regex_vn, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_acodec(self): command = self.commandQLE.text() text = self.audcodecQCB.currentText() regex = r'(\s+|^)-(acodec|c:a)\s+\S+(\s+|$)' regex_an = r'(\s+|^)-an(\s+|$)' if self.audcodecQCB.currentIndex() == 1: s = ' -an '.format(text) elif self.audcodecQCB.currentIndex() == 0: s = ' ' else: s = ' -acodec {0} '.format(text) if re.search(regex, command): command = re.sub(regex, s, command) elif re.search(regex_an, command): command = re.sub(regex_an, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_subtitles(self): command = self.commandQLE.text() regex = r'(,*\s*){0,1}(subtitles=\'.*\')(\s*,*\s*){0,1}' text = self.embedQLE.text() _filter = "subtitles='{0}'".format(text) if text else '' self.commandQLE.setText(utils.update_cmdline_text( command, _filter, regex, bool(text), 0, 2)) def command_update_rotation(self): command = self.commandQLE.text() regex = r'(,*\s*){0,1}(transpose=\d(,\s*transpose=\d)*|vflip|hflip)(\s*,*\s*){0,1}' rotate = self.rotateQCB.currentIndex() if rotate == 0: # none _filter = '' elif rotate == 1: # 90 clockwise _filter = 'transpose=1' elif rotate == 2: # 90 clockwise + vertical flip _filter = 'transpose=3' elif rotate == 3: # 90 counter clockwise _filter = 'transpose=2' elif rotate == 4: # 90 counter clockwise + vertical flip _filter = 'transpose=0' elif rotate == 5: # 180 _filter = 'transpose=2,transpose=2' elif rotate == 6: # horizontal flip _filter = 'hflip' elif rotate == 7: # vertical flip _filter = 'vflip' self.commandQLE.setText(utils.update_cmdline_text( command, _filter, regex, bool(rotate != 0), 0, 3))
class EditorAssembly(QWidget): """ Class implementing the editor assembly widget containing the navigation combos and the editor widget. """ def __init__(self, dbs, fn=None, vm=None, filetype="", editor=None, tv=None): """ Constructor @param dbs reference to the debug server object @param fn name of the file to be opened (string). If it is None, a new (empty) editor is opened @param vm reference to the view manager object (ViewManager.ViewManager) @param filetype type of the source file (string) @param editor reference to an Editor object, if this is a cloned view @param tv reference to the task viewer object """ super(EditorAssembly, self).__init__() self.__layout = QGridLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.__layout.setSpacing(1) self.__globalsCombo = QComboBox() self.__membersCombo = QComboBox() from .Editor import Editor self.__editor = Editor(dbs, fn, vm, filetype, editor, tv) self.__layout.addWidget(self.__globalsCombo, 0, 0) self.__layout.addWidget(self.__membersCombo, 0, 1) self.__layout.addWidget(self.__editor, 1, 0, 1, -1) self.__module = None self.__globalsCombo.activated[int].connect(self.__globalsActivated) self.__membersCombo.activated[int].connect(self.__membersActivated) self.__editor.cursorLineChanged.connect(self.__editorCursorLineChanged) self.__parseTimer = QTimer(self) self.__parseTimer.setSingleShot(True) self.__parseTimer.setInterval(5 * 1000) self.__parseTimer.timeout.connect(self.__parseEditor) self.__editor.textChanged.connect(self.__resetParseTimer) self.__editor.refreshed.connect(self.__resetParseTimer) self.__selectedGlobal = "" self.__selectedMember = "" self.__globalsBoundaries = {} self.__membersBoundaries = {} QTimer.singleShot(0, self.__parseEditor) def shutdownTimer(self): """ Public method to stop and disconnect the timer. """ self.__parseTimer.stop() self.__parseTimer.timeout.disconnect(self.__parseEditor) self.__editor.textChanged.disconnect(self.__resetParseTimer) self.__editor.refreshed.disconnect(self.__resetParseTimer) def getEditor(self): """ Public method to get the reference to the editor widget. @return reference to the editor widget (Editor) """ return self.__editor def __globalsActivated(self, index, moveCursor=True): """ Private method to jump to the line of the selected global entry and to populate the members combo box. @param index index of the selected entry (integer) @keyparam moveCursor flag indicating to move the editor cursor (boolean) """ # step 1: go to the line of the selected entry lineno = self.__globalsCombo.itemData(index) if lineno is not None: if moveCursor: txt = self.__editor.text(lineno - 1).rstrip() pos = len(txt.replace(txt.strip(), "")) self.__editor.gotoLine( lineno, pos if pos == 0 else pos + 1, True) self.__editor.setFocus() # step 2: populate the members combo, if the entry is a class self.__membersCombo.clear() self.__membersBoundaries = {} self.__membersCombo.addItem("") memberIndex = 0 entryName = self.__globalsCombo.itemText(index) if self.__module: if entryName in self.__module.classes: entry = self.__module.classes[entryName] elif entryName in self.__module.modules: entry = self.__module.modules[entryName] # step 2.0: add module classes items = {} for cl in entry.classes.values(): if cl.isPrivate(): icon = UI.PixmapCache.getIcon("class_private.png") elif cl.isProtected(): icon = UI.PixmapCache.getIcon( "class_protected.png") else: icon = UI.PixmapCache.getIcon("class.png") items[cl.name] = (icon, cl.lineno, cl.endlineno) for key in sorted(items.keys()): itm = items[key] self.__membersCombo.addItem(itm[0], key, itm[1]) memberIndex += 1 self.__membersBoundaries[(itm[1], itm[2])] = \ memberIndex else: return # step 2.1: add class methods from Utilities.ModuleParser import Function items = {} for meth in entry.methods.values(): if meth.modifier == Function.Static: icon = UI.PixmapCache.getIcon("method_static.png") elif meth.modifier == Function.Class: icon = UI.PixmapCache.getIcon("method_class.png") elif meth.isPrivate(): icon = UI.PixmapCache.getIcon("method_private.png") elif meth.isProtected(): icon = UI.PixmapCache.getIcon("method_protected.png") else: icon = UI.PixmapCache.getIcon("method.png") items[meth.name] = (icon, meth.lineno, meth.endlineno) for key in sorted(items.keys()): itm = items[key] self.__membersCombo.addItem(itm[0], key, itm[1]) memberIndex += 1 self.__membersBoundaries[(itm[1], itm[2])] = memberIndex # step 2.2: add class instance attributes items = {} for attr in entry.attributes.values(): if attr.isPrivate(): icon = UI.PixmapCache.getIcon("attribute_private.png") elif attr.isProtected(): icon = UI.PixmapCache.getIcon( "attribute_protected.png") else: icon = UI.PixmapCache.getIcon("attribute.png") items[attr.name] = (icon, attr.lineno) for key in sorted(items.keys()): itm = items[key] self.__membersCombo.addItem(itm[0], key, itm[1]) # step 2.3: add class attributes items = {} icon = UI.PixmapCache.getIcon("attribute_class.png") for glob in entry.globals.values(): items[glob.name] = (icon, glob.lineno) for key in sorted(items.keys()): itm = items[key] self.__membersCombo.addItem(itm[0], key, itm[1]) def __membersActivated(self, index, moveCursor=True): """ Private method to jump to the line of the selected members entry. @param index index of the selected entry (integer) @keyparam moveCursor flag indicating to move the editor cursor (boolean) """ lineno = self.__membersCombo.itemData(index) if lineno is not None and moveCursor: txt = self.__editor.text(lineno - 1).rstrip() pos = len(txt.replace(txt.strip(), "")) self.__editor.gotoLine(lineno, pos if pos == 0 else pos + 1, True) self.__editor.setFocus() def __resetParseTimer(self): """ Private slot to reset the parse timer. """ self.__parseTimer.stop() self.__parseTimer.start() def __parseEditor(self): """ Private method to parse the editor source and repopulate the globals combo. """ from Utilities.ModuleParser import Module, getTypeFromTypeName self.__module = None sourceType = getTypeFromTypeName(self.__editor.determineFileType()) if sourceType != -1: src = self.__editor.text() if src: fn = self.__editor.getFileName() if fn is None: fn = "" self.__module = Module("", fn, sourceType) self.__module.scan(src) # remember the current selections self.__selectedGlobal = self.__globalsCombo.currentText() self.__selectedMember = self.__membersCombo.currentText() self.__globalsCombo.clear() self.__membersCombo.clear() self.__globalsBoundaries = {} self.__membersBoundaries = {} self.__globalsCombo.addItem("") index = 0 # step 1: add modules items = {} for module in self.__module.modules.values(): items[module.name] = (UI.PixmapCache.getIcon("module.png"), module.lineno, module.endlineno) for key in sorted(items.keys()): itm = items[key] self.__globalsCombo.addItem(itm[0], key, itm[1]) index += 1 self.__globalsBoundaries[(itm[1], itm[2])] = index # step 2: add classes items = {} for cl in self.__module.classes.values(): if cl.isPrivate(): icon = UI.PixmapCache.getIcon("class_private.png") elif cl.isProtected(): icon = UI.PixmapCache.getIcon("class_protected.png") else: icon = UI.PixmapCache.getIcon("class.png") items[cl.name] = (icon, cl.lineno, cl.endlineno) for key in sorted(items.keys()): itm = items[key] self.__globalsCombo.addItem(itm[0], key, itm[1]) index += 1 self.__globalsBoundaries[(itm[1], itm[2])] = index # step 3: add functions items = {} for func in self.__module.functions.values(): if func.isPrivate(): icon = UI.PixmapCache.getIcon("method_private.png") elif func.isProtected(): icon = UI.PixmapCache.getIcon("method_protected.png") else: icon = UI.PixmapCache.getIcon("method.png") items[func.name] = (icon, func.lineno, func.endlineno) for key in sorted(items.keys()): itm = items[key] self.__globalsCombo.addItem(itm[0], key, itm[1]) index += 1 self.__globalsBoundaries[(itm[1], itm[2])] = index # step 4: add attributes items = {} for glob in self.__module.globals.values(): if glob.isPrivate(): icon = UI.PixmapCache.getIcon("attribute_private.png") elif glob.isProtected(): icon = UI.PixmapCache.getIcon( "attribute_protected.png") else: icon = UI.PixmapCache.getIcon("attribute.png") items[glob.name] = (icon, glob.lineno) for key in sorted(items.keys()): itm = items[key] self.__globalsCombo.addItem(itm[0], key, itm[1]) # reset the currently selected entries without moving the # text cursor index = self.__globalsCombo.findText(self.__selectedGlobal) if index != -1: self.__globalsCombo.setCurrentIndex(index) self.__globalsActivated(index, moveCursor=False) index = self.__membersCombo.findText(self.__selectedMember) if index != -1: self.__membersCombo.setCurrentIndex(index) self.__membersActivated(index, moveCursor=False) def __editorCursorLineChanged(self, lineno): """ Private slot handling a line change of the cursor of the editor. @param lineno line number of the cursor (integer) """ lineno += 1 # cursor position is zero based, code info one based # step 1: search in the globals for (lower, upper), index in self.__globalsBoundaries.items(): if upper == -1: upper = 1000000 # it is the last line if lower <= lineno <= upper: break else: index = 0 self.__globalsCombo.setCurrentIndex(index) self.__globalsActivated(index, moveCursor=False) # step 2: search in members for (lower, upper), index in self.__membersBoundaries.items(): if upper == -1: upper = 1000000 # it is the last line if lower <= lineno <= upper: break else: index = 0 self.__membersCombo.setCurrentIndex(index) self.__membersActivated(index, moveCursor=False)
class ProjectData(QWidget): def __init__(self, parent): super(ProjectData, self).__init__() self._parent = parent grid = QGridLayout(self) grid.addWidget(QLabel(_translate("ProjectData", "Name:")), 0, 0) self.name = QLineEdit() if self._parent._item.name == '': self.name.setText(file_manager.get_basename( self._parent._item.path)) else: self.name.setText(self._parent._item.name) grid.addWidget(self.name, 0, 1) grid.addWidget(QLabel(_translate("ProjectData", "Project Location:")), 1, 0) self.txtPath = QLineEdit() self.txtPath.setReadOnly(True) self.txtPath.setText(self._parent._item.path) grid.addWidget(self.txtPath, 1, 1) grid.addWidget(QLabel(_translate("ProjectData", "Project Type:")), 2, 0) self.txtType = QLineEdit() completer = QCompleter(sorted(settings.PROJECT_TYPES)) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.txtType.setCompleter(completer) self.txtType.setText(self._parent._item.projectType) grid.addWidget(self.txtType, 2, 1) grid.addWidget(QLabel(_translate("ProjectData", "Description:")), 3, 0) self.description = QPlainTextEdit() self.description.setPlainText(self._parent._item.description) grid.addWidget(self.description, 3, 1) grid.addWidget(QLabel(_translate("ProjectData", "URL:")), 4, 0) self.url = QLineEdit() self.url.setText(self._parent._item.url) grid.addWidget(self.url, 4, 1) grid.addWidget(QLabel(_translate("ProjectData", "Licence:")), 5, 0) self.cboLicense = QComboBox() self.cboLicense.addItem('Apache License 2.0') self.cboLicense.addItem('Artistic License/GPL') self.cboLicense.addItem('Eclipse Public License 1.0') self.cboLicense.addItem('GNU General Public License v2') self.cboLicense.addItem('GNU General Public License v3') self.cboLicense.addItem('GNU Lesser General Public License') self.cboLicense.addItem('MIT License') self.cboLicense.addItem('Mozilla Public License 1.1') self.cboLicense.addItem('Mozilla Public License 2.0') self.cboLicense.addItem('New BSD License') self.cboLicense.addItem('Other Open Source') self.cboLicense.addItem('Other') self.cboLicense.setCurrentIndex(4) index = self.cboLicense.findText(self._parent._item.license) self.cboLicense.setCurrentIndex(index) grid.addWidget(self.cboLicense, 5, 1) self.txtExtensions = QLineEdit() self.txtExtensions.setText(', '.join(self._parent._item.extensions)) grid.addWidget(QLabel(_translate("ProjectData", "Supported Extensions:")), 6, 0) grid.addWidget(self.txtExtensions, 6, 1) grid.addWidget(QLabel(_translate("ProjectData", "Indentation: ")), 7, 0) self.spinIndentation = QSpinBox() self.spinIndentation.setValue(self._parent._item.indentation) self.spinIndentation.setMinimum(1) grid.addWidget(self.spinIndentation, 7, 1) self.checkUseTabs = QCheckBox(_translate("ProjectData", "Use Tabs.")) self.checkUseTabs.setChecked(self._parent._item.useTabs) grid.addWidget(self.checkUseTabs, 7, 2)
class ProjectData(QWidget): """Project Data widget class""" def __init__(self, parent): super(ProjectData, self).__init__() self._parent = parent grid = QGridLayout(self) grid.addWidget(QLabel(translations.TR_PROJECT_NAME), 0, 0) self._line_name = QLineEdit() if not len(self._parent.project.name): self._line_name.setText(file_manager.get_basename( self._parent.project.path)) else: self._line_name.setText(self._parent.project.name) grid.addWidget(self._line_name, 0, 1) grid.addWidget(QLabel(translations.TR_PROJECT_LOCATION), 1, 0) self.line_path = QLineEdit() self.line_path.setReadOnly(True) self.line_path.setText(self._parent.project.path) grid.addWidget(self.line_path, 1, 1) grid.addWidget(QLabel(translations.TR_PROJECT_TYPE), 2, 0) self.line_type = QLineEdit() template_registry = IDE.get_service("template_registry") completer = QCompleter(template_registry.list_project_categories()) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.line_type.setCompleter(completer) self.line_type.setPlaceholderText("python") self.line_type.setText(self._parent.project.project_type) grid.addWidget(self.line_type, 2, 1) grid.addWidget(QLabel(translations.TR_PROJECT_DESCRIPTION), 3, 0) self._line_description = QPlainTextEdit() self._line_description.setPlainText(self._parent.project.description) grid.addWidget(self._line_description, 3, 1) grid.addWidget(QLabel(translations.TR_PROJECT_URL), 4, 0) self._line_url = QLineEdit() self._line_url.setText(self._parent.project.url) self._line_url.setPlaceholderText( 'https://www.{}.com'.format(getuser())) grid.addWidget(self._line_url, 4, 1) grid.addWidget(QLabel(translations.TR_PROJECT_LICENSE), 5, 0) self._combo_license = QComboBox() self._combo_license.addItems(LICENSES) self._combo_license.setCurrentIndex(12) index = self._combo_license.findText(self._parent.project.license) self._combo_license.setCurrentIndex(index) grid.addWidget(self._combo_license, 5, 1) self._line_extensions = QLineEdit() self._line_extensions.setText( ', '.join(self._parent.project.extensions)) self._line_extensions.setToolTip( translations.TR_PROJECT_EXTENSIONS_TOOLTIP) grid.addWidget(QLabel(translations.TR_PROJECT_EXTENSIONS), 6, 0) grid.addWidget(self._line_extensions, 6, 1) labelTooltip = QLabel(translations.TR_PROJECT_EXTENSIONS_INSTRUCTIONS) grid.addWidget(labelTooltip, 7, 1) grid.addWidget(QLabel(translations.TR_PROJECT_INDENTATION), 8, 0) self._spin_indentation = QSpinBox() self._spin_indentation.setValue(self._parent.project.indentation) self._spin_indentation.setRange(2, 10) self._spin_indentation.setValue(4) self._spin_indentation.setSingleStep(2) grid.addWidget(self._spin_indentation, 8, 1) self._combo_tabs_or_spaces = QComboBox() self._combo_tabs_or_spaces.addItems([ translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES.capitalize(), translations.TR_PREFERENCES_EDITOR_CONFIG_TABS.capitalize()]) self._combo_tabs_or_spaces.setCurrentIndex( int(self._parent.project.use_tabs)) grid.addWidget(self._combo_tabs_or_spaces, 9, 1) @property def name(self): return self._line_name.text() @property def path(self): return self.line_path.text() @property def project_type(self): return self.line_type.text() @property def description(self): return self._line_description.toPlainText() @property def url(self): return self._line_url.text() @property def license(self): return self._combo_license.currentText() @property def extensions(self): return list(map(str.strip, self._line_extensions.text().split(','))) @property def indentation(self): return self._spin_indentation.value() @property def use_tabs(self): return bool(self._combo_tabs_or_spaces.currentIndex())
class TreeLayerItem(QTreeWidgetItem): layerIcon = QIcon(os.path.join(os.path.dirname(__file__), "icons", "layer.png")) def __init__(self, iface, layer, tree, dlg): QTreeWidgetItem.__init__(self) self.iface = iface self.layer = layer self.setText(0, layer.name()) self.setIcon(0, self.layerIcon) project = QgsProject.instance() if project.layerTreeRoot().findLayer(layer.id()).isVisible(): self.setCheckState(0, Qt.Checked) else: self.setCheckState(0, Qt.Unchecked) self.visibleItem = QTreeWidgetItem(self) self.visibleCheck = QCheckBox() vis = layer.customProperty("qgis2web/Visible", True) if (vis == 0 or unicode(vis).lower() == "false"): self.visibleCheck.setChecked(False) else: self.visibleCheck.setChecked(True) self.visibleItem.setText(0, "Visible") self.addChild(self.visibleItem) tree.setItemWidget(self.visibleItem, 1, self.visibleCheck) if layer.type() == layer.VectorLayer: if layer.providerType() == 'WFS': self.jsonItem = QTreeWidgetItem(self) self.jsonCheck = QCheckBox() if layer.customProperty("qgis2web/Encode to JSON") == 2: self.jsonCheck.setChecked(True) self.jsonItem.setText(0, "Encode to JSON") self.jsonCheck.stateChanged.connect(self.changeJSON) self.addChild(self.jsonItem) tree.setItemWidget(self.jsonItem, 1, self.jsonCheck) if layer.geometryType() == QgsWkbTypes.PointGeometry: self.clusterItem = QTreeWidgetItem(self) self.clusterCheck = QCheckBox() if layer.customProperty("qgis2web/Cluster") == 2: self.clusterCheck.setChecked(True) self.clusterItem.setText(0, "Cluster") self.clusterCheck.stateChanged.connect(self.changeCluster) self.addChild(self.clusterItem) tree.setItemWidget(self.clusterItem, 1, self.clusterCheck) self.popupItem = QTreeWidgetItem(self) self.popupItem.setText(0, "Popup fields") options = [] fields = self.layer.fields() for f in fields: fieldIndex = fields.indexFromName(unicode(f.name())) editorWidget = layer.editorWidgetSetup(fieldIndex).type() if editorWidget == 'Hidden': continue options.append(f.name()) for option in options: self.attr = QTreeWidgetItem(self) self.attrWidget = QComboBox() self.attrWidget.addItem("no label") self.attrWidget.addItem("inline label") self.attrWidget.addItem("header label") custProp = layer.customProperty("qgis2web/popup/" + option) if (custProp != "" and custProp is not None): self.attrWidget.setCurrentIndex( self.attrWidget.findText( layer.customProperty("qgis2web/popup/" + option))) self.attr.setText(1, option) self.popupItem.addChild(self.attr) tree.setItemWidget(self.attr, 2, self.attrWidget) self.addChild(self.popupItem) else: if layer.providerType() == 'wms': self.getFeatureInfoItem = QTreeWidgetItem(self) self.getFeatureInfoCheck = QCheckBox() if layer.customProperty("qgis2web/GetFeatureInfo") == 2: self.getFeatureInfoCheck.setChecked(True) self.getFeatureInfoItem.setText(0, "Enable GetFeatureInfo?") self.getFeatureInfoCheck.stateChanged.connect( self.changeGetFeatureInfo) self.addChild(self.getFeatureInfoItem) tree.setItemWidget(self.getFeatureInfoItem, 1, self.getFeatureInfoCheck) @property def popup(self): popup = [] self.tree = self.treeWidget() for p in range(self.childCount()): item = self.child(p).text(1) if item != "": popupVal = self.tree.itemWidget(self.child(p), 2).currentText() pair = (item, popupVal) popup.append(pair) popup = OrderedDict(popup) return popup @property def visible(self): return self.visibleCheck.isChecked() @property def json(self): try: return self.jsonCheck.isChecked() except: return False @property def cluster(self): try: return self.clusterCheck.isChecked() except: return False @property def getFeatureInfo(self): try: return self.getFeatureInfoCheck.isChecked() except: return False def changeJSON(self, isJSON): self.layer.setCustomProperty("qgis2web/Encode to JSON", isJSON) def changeCluster(self, isCluster): self.layer.setCustomProperty("qgis2web/Cluster", isCluster) def changeGetFeatureInfo(self, isGetFeatureInfo): self.layer.setCustomProperty("qgis2web/GetFeatureInfo", isGetFeatureInfo)
class TreeSettingItem(QTreeWidgetItem): def __init__(self, parent, tree, name, value, action=None): QTreeWidgetItem.__init__(self, parent) self.parent = parent self.tree = tree self.name = name self._value = value self.combo = None self.setText(0, name) widget = None if isinstance(value, bool): if value: self.setCheckState(1, Qt.Checked) else: self.setCheckState(1, Qt.Unchecked) elif isinstance(value, tuple): self.combo = QComboBox() self.combo.setSizeAdjustPolicy(0) for option in value: self.combo.addItem(option) widget = self.combo else: self.setText(1, unicode(value)) if action: layout = QHBoxLayout() layout.setMargin(0) if widget: layout.addWidget(widget) button = QToolButton() button.setDefaultAction(action) button.setText(action.text()) layout.addWidget(button) layout.addStretch(1) widget = QWidget() widget.setLayout(layout) if widget: self.tree.setItemWidget(self, 1, widget) def setValue(self, value): if isinstance(value, bool): if value: self.setCheckState(1, Qt.Checked) else: self.setCheckState(1, Qt.Unchecked) elif self.combo: index = self.combo.findText(value) if index != -1: self.combo.setCurrentIndex(index) else: self.setText(1, unicode(value)) def value(self): if isinstance(self._value, bool): return self.checkState(1) == Qt.Checked elif isinstance(self._value, (int, float)): return float(self.text(1)) elif isinstance(self._value, tuple): return self.combo.currentText() else: return self.text(1)
class GeneralExecution(QWidget): """General Execution widget class""" def __init__(self, parent): super().__init__() self._preferences = parent box = QVBoxLayout(self) group_python_path = QGroupBox(translations.TR_WORKSPACE_PROJECTS) group_python_opt = QGroupBox(translations.TR_PYTHON_OPTIONS) vbox = QVBoxLayout(group_python_path) box_path = QVBoxLayout() # Line python path hbox_path = QHBoxLayout() self._combo_python_path = QComboBox() self._combo_python_path.setEditable(True) self._combo_python_path.addItems(utils.get_python()) hbox_path.addWidget(self._combo_python_path) self._combo_python_path.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) btn_choose_path = QPushButton( self.style().standardIcon(self.style().SP_DirIcon), '') box_path.addWidget( QLabel( translations.TR_PREFERENCES_EXECUTION_PYTHON_INTERPRETER_LBL)) hbox_path.addWidget(btn_choose_path) box_path.addLayout(hbox_path) vbox.addLayout(box_path) # Python Miscellaneous Execution options vbox_opts = QVBoxLayout(group_python_opt) self._check_B = QCheckBox(translations.TR_SELECT_EXEC_OPTION_B) self._check_d = QCheckBox(translations.TR_SELECT_EXEC_OPTION_D) self._check_E = QCheckBox(translations.TR_SELECT_EXEC_OPTION_E) self._check_O = QCheckBox(translations.TR_SELECT_EXEC_OPTION_O) self._check_OO = QCheckBox(translations.TR_SELECT_EXEC_OPTION_OO) self._check_s = QCheckBox(translations.TR_SELECT_EXEC_OPTION_s) self._check_S = QCheckBox(translations.TR_SELECT_EXEC_OPTION_S) self._check_v = QCheckBox(translations.TR_SELECT_EXEC_OPTION_V) hbox = QHBoxLayout() self._check_W = QCheckBox(translations.TR_SELECT_EXEC_OPTION_W) self._combo_warning = QComboBox() self._combo_warning.addItems([ "default", "ignore", "all", "module", "once", "error" ]) self._check_W.stateChanged.connect( lambda state: self._combo_warning.setEnabled(bool(state))) vbox_opts.addWidget(self._check_B) vbox_opts.addWidget(self._check_d) vbox_opts.addWidget(self._check_E) vbox_opts.addWidget(self._check_O) vbox_opts.addWidget(self._check_OO) vbox_opts.addWidget(self._check_s) vbox_opts.addWidget(self._check_S) vbox_opts.addWidget(self._check_v) hbox.addWidget(self._check_W) hbox.addWidget(self._combo_warning) vbox_opts.addLayout(hbox) """ completer = QCompleter(self) dirs = QDirModel(self) dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) completer.setModel(dirs) self._txt_python_path.setCompleter(completer) box_path.addWidget(default_interpreter_radio) box_path.addWidget(custom_interpreter_radio) """ box.addWidget(group_python_path) box.addWidget(group_python_opt) box.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) # Settings self._combo_python_path.setCurrentText(settings.PYTHON_EXEC) options = settings.EXECUTION_OPTIONS.split() if "-B" in options: self._check_B.setChecked(True) if "-d" in options: self._check_d.setChecked(True) if "-E" in options: self._check_E.setChecked(True) if "-O" in options: self._check_O.setChecked(True) if "-OO" in options: self._check_OO.setChecked(True) if "-S" in options: self._check_S.setChecked(True) if "-s" in options: self._check_s.setChecked(True) if "-v" in options: self._check_v.setChecked(True) if settings.EXECUTION_OPTIONS.find("-W") > -1: self._check_W.setChecked(True) index = settings.EXECUTION_OPTIONS.find("-W") opt = settings.EXECUTION_OPTIONS[index + 2:].strip() index = self._combo_warning.findText(opt) self._combo_warning.setCurrentIndex(index) # Connections self._preferences.savePreferences.connect(self.save) btn_choose_path.clicked.connect(self._load_python_path) @pyqtSlot() def _load_python_path(self): """Ask the user for a Python Path""" path = QFileDialog.getOpenFileName( self, translations.TR_SELECT_SELECT_PYTHON_EXEC)[0] if path: self._combo_python_path.setEditText(path) def save(self): """Save all Execution Preferences""" qsettings = IDE.ninja_settings() qsettings.beginGroup("execution") # Python executable settings.PYTHON_EXEC = self._combo_python_path.currentText() qsettings.setValue("pythonExec", settings.PYTHON_EXEC) # Execution options options = "" if self._check_B.isChecked(): options += " -B" if self._check_d.isChecked(): options += " -d" if self._check_E.isChecked(): options += " -E" if self._check_O.isChecked(): options += " -O" if self._check_OO.isChecked(): options += " -OO" if self._check_s.isChecked(): options += " -s" if self._check_S.isChecked(): options += " -S" if self._check_v.isChecked(): options += " -v" if self._check_W.isChecked(): options += " -W" + self._combo_warning.currentText() settings.EXECUTION_OPTIONS = options qsettings.setValue("executionOptions", options) qsettings.endGroup()
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowIcon(QIcon('icon.png')) self.ui.actionLoad_Lyrics.triggered.connect(self._load_lyrics_thread) self.cb_backends() # about widget self.aboutUi = About() self.ui.actionAbout.triggered.connect(self._about) self.aboutUi.setWindowModality(Qt.WindowModal) self._load_lyrics_thread() def cb_backends(self): self.cb_backends = QComboBox() self.cb_backends.addItem('Auto') menuLyricSource = QMenu(self.ui.menuEdit) menuLyricSource.setTitle('Lyric source') self.lyricGroup = QActionGroup(self) def addAction(name, checked=False): action = QAction(name, self) action.setText(name) action.setCheckable(True) action.setChecked(checked) action.setActionGroup(self.lyricGroup) return action menuLyricSource.addAction(addAction('Auto', True)) menuLyricSource.addSeparator() menuLyricSource.triggered.connect(self._menu_backend_change) for backend in Pyrics.get_backends(): menuLyricSource.addAction(addAction(backend.__name__)) self.cb_backends.addItem(backend.__name__) self.ui.menuEdit.addMenu(menuLyricSource) self.ui.toolBar.addWidget(self.cb_backends) self.cb_backends.currentIndexChanged.connect(self._cb_backend_change) def _load_lyrics_thread(self): self.thread = LoadLyricsWorker(self.cb_backends.currentIndex(), self) self.thread.trigger.connect(self._load_lyrics) self.thread.start() def _load_lyrics(self, content): self.ui.txLyrics.setText(content) def _about(self): self.aboutUi.show() def _menu_backend_change(self, action): index = self.cb_backends.findText(action.text()) self._update_backend(index) def _cb_backend_change(self, item): self._update_backend(item) def _update_backend(self, index): """Keep lyrics source combo in sync with the lyrics source in the menu""" if index >= 0: self.cb_backends.setCurrentIndex(index) name = self.cb_backends.currentText() for action in self.lyricGroup.actions(): action.setChecked(False) if action.text() == name: action.setChecked(True)
class MainView(base, form): def __init__(self, pipeline, parent=None): super(base, self).__init__(parent) self.setupUi(self) self.pipeline = pipeline self.pip_widgets = [] self.default_pips = [] self.draw_ui() self.connect_ui() def register_observers(self): pass def connect_ui(self): """ This function connects the ui using signals from the ui elements and its method counterparts. """ self.input_btn.clicked.connect(self.set_input_url) self.output_btn.clicked.connect(self.set_output_url) self.save_btn.clicked.connect(self.save_pipeline) self.load_favorite_pipelines() self.fav_pips_combo_box.activated.connect(self.select_default_pip) self.run_btn.clicked.connect(self.run) self.delete_btn.clicked.connect(self.trash_pipeline) self.add_btn.clicked.connect(lambda: self.add_pipe_entry_new()) def draw_ui(self): """ This function draws all additional UI elements. If you want the application to display any additional things like a button you can either add it in the QtDesigner or declare it here. """ # *TODO* Create these ones with Qt Designer and put them into select_cat_alg_vbox_layout. I failed self.ComboxCategories = QComboBox() self.stackedWidgetComboxesAlgorithms = QStackedWidget() self.select_cat_alg_vbox_layout.addWidget(self.ComboxCategories) self.select_cat_alg_vbox_layout.addWidget(self.stackedWidgetComboxesAlgorithms) self.ComboxCategories.hide() """ This function is concerned with drawing all non static elements into the GUI. """ """self.set_pip_title("A. Junius2") self.set_preset(["A.Junius", "test", "test", "test"]) self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_cat_image("../assets/images/seg_fav.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.main_image_label.setPixmap(QtGui.QPixmap("wing.jpeg")) category_combo_box = ComboBoxWidget("type") category_combo_box.add_item("Preprocessing", "../assets/images/P.png") category_combo_box.add_item("Segmentation", "../assets/images/S.png") category_combo_box.add_item("Graph Detection", "../assets/images/D.png") category_combo_box.add_item("Graph Filtering", "../assets/images/F.png") alg_combo_box = ComboBoxWidget("algorithm") alg_combo_box.add_item("Otsus") alg_combo_box.add_item("Guo Hall") alg_combo_box.add_item("Adaptive Treshold") slider_1 = SliderWidget("slider1das", 0, 10, 1, 4, True) slider_2 = SliderWidget("slider1", 0, 10, 2, 4, False) slider_3 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True) slider_4 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True) slider_5 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True) checkbox_1 = CheckBoxWidget("checkbox1", True) self.setting_widget_vbox_layout.addWidget(category_combo_box) self.setting_widget_vbox_layout.addWidget(alg_combo_box) self.setting_widget_vbox_layout.addWidget(slider_1) self.setting_widget_vbox_layout.addWidget(slider_2) self.setting_widget_vbox_layout.addWidget(slider_3) self.setting_widget_vbox_layout.addWidget(slider_4) self.setting_widget_vbox_layout.addWidget(slider_5) self.setting_widget_vbox_layout.addWidget(checkbox_1) self.setting_widget_vbox_layout.setAlignment(Qt.AlignTop)""" def set_pip_title(self, title): """ Sets the title of the current selected pipeline in the ui. Args: | *title*: the title of the pipeline | *label_ref*: the reference to the label. """ self.current_pip_label.setText(title) def load_dark_theme(self, application): """ This function is called to load the white theme with all its icons for the buttons and the css file. Args: application: the cureent app instance """ # load buttons pixmap_icon = QtGui.QPixmap("./assets/images/add_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.add_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/trash_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.delete_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/diskette_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.save_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/up-arrow_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.input_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/folder_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.output_btn.setIcon(q_icon) @pyqtSlot(int) def select_default_pip(self, index): """ This is the slot for the Pipeline combobox in the ui Args: index: index of the option currently selected """ # delete current pipeline self.trash_pipeline() # get url and name name, url = self.default_pips[index - 1] # parse the json in the model self.pipeline.load_pipeline_json(url) print("PARSER" + str(self.pipeline.executed_cats[0].active_algorithm)) print("PARSER" + str(self.pipeline.executed_cats[1].active_algorithm)) # set the title self.set_pip_title(name) # Create an entry in the pipeline widget for every step in the pipeline for i in range(0, len(self.pipeline.executed_cats)): self.add_pipe_entry_new(i) self.scroll_down_pip() """for widget in alg_widgets: self.setting_widget_vbox_layout.addWidget(widget)""" def trash_pipeline(self): """ This method clears the complete pipeline while users clicked the trash button. """ # remove all entries in the pipeline list while self.pip_widget_vbox_layout.count(): child = self.pip_widget_vbox_layout.takeAt(0) child.widget().deleteLater() while self.stackedWidget_Settings.currentWidget() is not None: self.stackedWidget_Settings.removeWidget(self.stackedWidget_Settings.currentWidget()) self.settings_collapsable.setTitle("") # remove the pipeline name self.set_pip_title("") # remove all entries int the executed_cats of the model pipeline del self.pipeline.executed_cats[:] # remove all widgets del self.pip_widgets[:] # remove category algorith dropdown self.remove_cat_alg_dropdown() # remove all entries from the pipeline model del self.pipeline.executed_cats[:] @pyqtSlot() def run(self): """ This method runs the the pipeline by calling the process methode in pipeline """ self.pipeline.process() @pyqtSlot() def set_input_url(self): """ This method sets the url for the input image in the pipeline. """ url = QtWidgets.QFileDialog.getOpenFileNames() if url[0]: print(url[0]) print(url[0][0]) self.lineEdit.setText(url[0][0]) self.pipeline.set_input(url[0][0]) @pyqtSlot() def set_output_url(self): """ This method sets the url for the output folder in the pipeline. Args: url: the url to the output folder a user selected in the ui """ url = QtWidgets.QFileDialog.getExistingDirectory() if url: print(url) print(url) self.custom_line_edit.setText(url) self.pipeline.set_output_dir(url) def load_favorite_pipelines(self): """ Scans the directory for default pipelines to display all available items """ self.fav_pips_combo_box.addItem("Please Select") # scan the directory for default pipelines for file in os.listdir("./_default_pipelines"): if file.endswith(".json"): name = file.split(".")[0] url = os.path.abspath("./_default_pipelines" + "/" + file) self.default_pips.append([name, url]) self.fav_pips_combo_box.addItem(name) @pyqtSlot() def save_pipeline(self): """ Saves the pipeline as a json at the users file system. """ url = str(QtWidgets.QFileDialog.getSaveFileName()[0]) split_list = url.split("/") name = split_list[len(split_list) - 1].split(".")[0] del split_list[len(split_list) - 1] url = url.replace(name, "") self.pipeline.save_pipeline_json(name, url) @pyqtSlot(int) def remove_pip_entry(self, pipe_entry_widget, settings_widget, cat=None): """ Removes the pip entry at the given position in the ui Args: pipeline_index (object): settings_widget: position: position at which the pip entry gets removed """ # remove pipeline entry widget from ui self.pip_widget_vbox_layout.removeWidget(pipe_entry_widget) pipe_entry_widget.deleteLater() # remove it settings widgets from ui if settings_widget is not None: if self.stackedWidget_Settings.currentWidget() == settings_widget: self.stackedWidget_Settings.hide() self.remove_cat_alg_dropdown() self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.removeWidget(settings_widget) # remove in model if cat is not None: print("Remove entry at pos " + str(self.pipeline.get_index(cat)) + " " + str(cat)) self.pipeline.delete_category(self.pipeline.get_index(cat)) def change_pip_entry_alg(self, position, new_category, new_algorithm, pipe_entry_widget, settings_widget): """ Changes the selected algorithm of the pipeline entry at the position. Afterwards create all widgets for this algorithm instance Args: position: the position of the pipeline entry algorithm: the selected algorithm for this category """ print("Position to be changed:" + str(position)) print("Pipeline length: " + str(len(self.pipeline.executed_cats))) old_cat = self.pipeline.executed_cats[position] old_alg = old_cat.active_algorithm print("Old Cat found in pipeline: " + str(old_cat)) print("Old Alg: found in pipeline:" + str(old_alg)) print("New Category given:" + str(new_category)) print("New Algorithm given:" + str(new_algorithm)) # set in model self.pipeline.change_category(new_category, position) self.pipeline.change_algorithm(new_algorithm, position) new_cat = self.pipeline.executed_cats[position] new_alg = new_cat.active_algorithm # change settings widgets self.remove_pip_entry(pipe_entry_widget, settings_widget) (new_pipe_entry_widget, new_settings_widget) = self.add_pipe_entry_new(position) self.stackedWidget_Settings.show() self.stackedWidget_Settings.setCurrentIndex(position) self.settings_collapsable.setTitle(new_alg.get_name() + " Settings") self.remove_cat_alg_dropdown() self.create_cat_alg_dropdown(position, new_pipe_entry_widget, new_settings_widget) self.set_cat_alg_dropdown(new_cat, new_alg) print("New Cat found in pipeline: " + str(new_cat)) print("New Alg found in pipeline: " + str(new_alg)) def load_settings_widgets_from_pipeline_groupbox(self, position): """ Extracts all widgets from a single algorithm and returns a QBoxLayout Args: alg: the alg instance we extract from Returns: a QBoxLayout containing all widgets for this particular alg. """ alg = self.pipeline.executed_cats[position].active_algorithm print("alg " + str(alg)) print("cat " + str(self.pipeline.executed_cats[position])) empty_flag = True groupOfSliders = QGroupBox() sp = QSizePolicy() sp.setVerticalPolicy(QSizePolicy.Preferred) # groupOfSliders.setSizePolicy(sp) groupOfSliderssLayout = QBoxLayout(QBoxLayout.TopToBottom) groupOfSliderssLayout.setContentsMargins(0, -0, -0, 0) groupOfSliderssLayout.setAlignment(Qt.AlignTop) groupOfSliderssLayout.setSpacing(0) print("Build Slider @ "+ str(position)) # create integer sliders for slider in alg.integer_sliders: empty_flag = False print("slider.value " + str(slider.value)) print("slider " + str(slider)) #print(alg.get_name() + ": add slider (int).") groupOfSliderssLayout.addWidget( SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value, slider.set_value, False)) # create float sliders for slider in alg.float_sliders: empty_flag = False #print(alg.get_name() + ": add slider (float).") groupOfSliderssLayout.addWidget( SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value, slider.set_value, True), 0, Qt.AlignTop) # create checkboxes for checkbox in alg.checkboxes: empty_flag = False #print(alg.get_name() + ": add checkbox.") groupOfSliderssLayout.addWidget(CheckBoxWidget(checkbox.name, checkbox.value, checkbox.set_value), 0, Qt.AlignTop) # create dropdowns for combobox in alg.drop_downs: empty_flag = False #print(alg.get_name() + ": add combobox.") groupOfSliderssLayout.addWidget( ComboBoxWidget(combobox.name, combobox.options, combobox.set_value, combobox.value), 0, Qt.AlignTop) if empty_flag: label = QLabel() label.setText("This algorithm has no Settings.") groupOfSliderssLayout.addWidget(label, 0, Qt.AlignHCenter) groupOfSliders.setLayout(groupOfSliderssLayout) return groupOfSliders def create_cat_alg_dropdown(self, cat_position, pipe_entry_widget, settings_widget): """ Args: last_cat (object): """ layout = self.select_cat_alg_vbox_layout cat = self.pipeline.executed_cats[cat_position] last_cat = None # Show only allowed categories in dropdown if len(self.pipeline.executed_cats) > 1: last_cat = self.pipeline.executed_cats[cat_position - 1] # Combobox for selecting Category self.ComboxCategories.show() self.ComboxCategories.setFixedHeight(30) self.ComboxCategories.addItem("<Please Select Category>") self.stackedWidgetComboxesAlgorithms = QStackedWidget() self.stackedWidgetComboxesAlgorithms.setFixedHeight(30) self.stackedWidgetComboxesAlgorithms.hide() def setCurrentIndexCat(index): #print("Set Cat") if self.ComboxCategories.currentIndex() == 0: self.stackedWidgetComboxesAlgorithms.hide() else: self.stackedWidgetComboxesAlgorithms.show() self.stackedWidgetComboxesAlgorithms.setCurrentIndex(index - 1) for category_name in self.pipeline.report_available_cats(last_cat): # Add Category to combobox self.ComboxCategories.addItem(category_name) tmp1 = QComboBox() tmp1.addItem("<Please Select Algorithm>") tmp1.setFixedHeight(30) category = self.pipeline.get_category(category_name) #self.current_index = -1 def setCurrentIndexAlg(index): if self.ComboxCategories.currentIndex() == 0 or self.stackedWidgetComboxesAlgorithms.currentWidget().currentIndex() == 0: pass else: #self.current_index != index: self.change_pip_entry_alg(self.pipeline.get_index(cat), self.ComboxCategories.currentText(), self.stackedWidgetComboxesAlgorithms.currentWidget().currentText(), pipe_entry_widget, settings_widget) #self.current_index = index tmp1.activated.connect(setCurrentIndexAlg) for algorithm_name in self.pipeline.get_all_algorithm_list(category): tmp1.addItem(algorithm_name) self.stackedWidgetComboxesAlgorithms.addWidget(tmp1) layout.addWidget(self.ComboxCategories) layout.addWidget(self.stackedWidgetComboxesAlgorithms) self.ComboxCategories.activated.connect(setCurrentIndexCat) def set_cat_alg_dropdown(self, category, algorithm): indexC = self.ComboxCategories.findText(category.get_name()) #print("IndexC " + str(indexC)) self.ComboxCategories.setCurrentIndex(indexC) self.stackedWidgetComboxesAlgorithms.show() self.stackedWidgetComboxesAlgorithms.setCurrentIndex(indexC - 1) indexA = self.stackedWidgetComboxesAlgorithms.currentWidget().findText(algorithm.get_name()) #print("IndexA " + str(indexA)) self.stackedWidgetComboxesAlgorithms.currentWidget().setCurrentIndex(indexA) def remove_cat_alg_dropdown(self): """ Returns: object: """ self.ComboxCategories.clear() while self.stackedWidgetComboxesAlgorithms.currentWidget() is not None: self.stackedWidgetComboxesAlgorithms.removeWidget(self.stackedWidgetComboxesAlgorithms.currentWidget()) while self.select_cat_alg_vbox_layout.count(): child = self.select_cat_alg_vbox_layout.takeAt(0) child.widget().hide() def scroll_down_pip(self): self.pip_scroll.verticalScrollBar().setSliderPosition(self.pip_scroll.verticalScrollBar().maximum()) def add_pipe_entry_new(self, position=None): """ Creates a entry in the ui pipeline with a given position in pipeline. It also creates the corresponding settings widget. """ # create an widget that displays the pip entry in the ui and connect the remove button pip_main_widget = QWidget() pip_main_widget.setFixedHeight(70) pip_main_widget.setFixedWidth(300) pip_main_layout = QHBoxLayout() pip_main_widget.setLayout(pip_main_layout) new_marker = False if position is None: position = len(self.pipeline.executed_cats) cat = self.pipeline.new_category(position) label = "<Click to specify new step>" icon = None new_marker = True else: cat = self.pipeline.executed_cats[position] alg = cat.active_algorithm label = alg.get_name() icon = cat.get_icon() new_marker = False pixmap = QPixmap(icon) pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio) pixmap_label = QtWidgets.QLabel() pixmap_label.setPixmap(pixmap_scaled_keeping_aspec) pip_up_down = QWidget() pip_up_down.setFixedHeight(70) pip_up_down_layout = QVBoxLayout() pip_up_down.setLayout(pip_up_down_layout) up_btn = QToolButton() dw_btn = QToolButton() up_btn.setArrowType(Qt.UpArrow) up_btn.setFixedHeight(25) dw_btn.setArrowType(Qt.DownArrow) dw_btn.setFixedHeight(25) pip_up_down_layout.addWidget(up_btn) pip_up_down_layout.addWidget(dw_btn) string_label = QLabel() string_label.setText(label) string_label.setFixedWidth(210) btn = QtWidgets.QPushButton() btn.setFixedSize(20, 20) pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png") q_icon = QtGui.QIcon(pixmap_icon) btn.setIcon(q_icon) pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter) pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter) pip_main_layout.addWidget(string_label, Qt.AlignLeft) pip_main_layout.addWidget(btn, Qt.AlignVCenter) self.pip_widget_vbox_layout.insertWidget(position, pip_main_widget) # Create the corresponding settings widget and connect it self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.hide() settings_main_widget = None if not new_marker: settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(position) self.stackedWidget_Settings.insertWidget(position, settings_main_widget) def show_settings(): # Set background color while widget is selected. Doesn't work because of theme? *TODO* p = pip_main_widget.palette() p.setColor(pip_main_widget.backgroundRole(), Qt.red) pip_main_widget.setPalette(p) if not new_marker: self.stackedWidget_Settings.show() self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat)) self.settings_collapsable.setTitle(alg.get_name() + " Settings") else: self.stackedWidget_Settings.hide() # Create drop down for cats and algs self.remove_cat_alg_dropdown() self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget) if not new_marker: self.set_cat_alg_dropdown(cat, alg) # Connect Button to remove step from pipeline def delete_button_clicked(): self.remove_cat_alg_dropdown() self.remove_pip_entry(pip_main_widget, settings_main_widget, cat) self.clickable(pixmap_label).connect(show_settings) self.clickable(string_label).connect(show_settings) btn.clicked.connect(delete_button_clicked) return (pip_main_widget, settings_main_widget) def add_pip_entry_empty(self): """ Creates an blank entry in the ui pipeline since the user still needs to specify a type and an algorithm of the category. It also creates the corresponding settings widget. """ # create an widget that displays the pip entry in the ui and connect the remove button pip_main_widget = QWidget() pip_main_widget.setFixedHeight(70) pip_main_widget.setFixedWidth(300) pip_main_layout = QHBoxLayout() pip_main_widget.setLayout(pip_main_layout) label = "<Click to specify new step>" icon = None pixmap = QPixmap(icon) pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio) pixmap_label = QtWidgets.QLabel() pixmap_label.setPixmap(pixmap_scaled_keeping_aspec) pip_up_down = QWidget() pip_up_down.setFixedHeight(70) pip_up_down_layout = QVBoxLayout() pip_up_down.setLayout(pip_up_down_layout) up_btn = QToolButton() dw_btn = QToolButton() up_btn.setArrowType(Qt.UpArrow) up_btn.setFixedHeight(25) dw_btn.setArrowType(Qt.DownArrow) dw_btn.setFixedHeight(25) pip_up_down_layout.addWidget(up_btn) pip_up_down_layout.addWidget(dw_btn) string_label = QLabel() string_label.setText(label) string_label.setFixedWidth(210) btn = QtWidgets.QPushButton() btn.setFixedSize(20, 20) pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png") q_icon = QtGui.QIcon(pixmap_icon) btn.setIcon(q_icon) pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter) pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter) pip_main_layout.addWidget(string_label, Qt.AlignLeft) pip_main_layout.addWidget(btn, Qt.AlignVCenter) cat_position = len(self.pipeline.executed_cats) self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget) index = self.pip_widget_vbox_layout.indexOf(pip_main_widget) #print(index) # Create the corresponding empty settings widget and connect it # settings = self.load_widgets_from_cat_groupbox(cat_position) *TODO* EMPTY self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.hide() # Add new step to pipeline new_category = self.pipeline.new_category(cat_position) print("Create new entry " + str(new_category)) print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".") settings_main_widget = None # Connect pipeline entry with corresponding settings widget def show_settings(): #print("click") self.stackedWidget_Settings.show() self.remove_cat_alg_dropdown() # Create drop down for cats and algs self.create_cat_alg_dropdown(self.pipeline.get_index(new_category), pip_main_widget, settings_main_widget) self.stackedWidget_Settings.hide() # Connect Button to remove step from pipeline def delete_button_clicked(): self.remove_cat_alg_dropdown() self.remove_pip_entry(pip_main_widget, settings_main_widget, new_category) self.clickable(pixmap_label).connect(show_settings) self.clickable(string_label).connect(show_settings) btn.clicked.connect(delete_button_clicked) self.scroll_down_pip() def add_pip_entry(self, cat_position): """ Creates a entry in the ui pipeline with a given position in pipeline. It also creates the corresponding settings widget. """ # create an widget that displays the pip entry in the ui and connect the remove button pip_main_widget = QWidget() pip_main_widget.setFixedHeight(70) pip_main_widget.setFixedWidth(300) pip_main_layout = QHBoxLayout() pip_main_widget.setLayout(pip_main_layout) cat = self.pipeline.executed_cats[cat_position] alg = cat.active_algorithm label = alg.get_name() icon = cat.get_icon() pixmap = QPixmap(icon) pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio) pixmap_label = QtWidgets.QLabel() pixmap_label.setPixmap(pixmap_scaled_keeping_aspec) pip_up_down = QWidget() pip_up_down.setFixedHeight(70) pip_up_down_layout = QVBoxLayout() pip_up_down.setLayout(pip_up_down_layout) up_btn = QToolButton() dw_btn = QToolButton() up_btn.setArrowType(Qt.UpArrow) up_btn.setFixedHeight(25) dw_btn.setArrowType(Qt.DownArrow) dw_btn.setFixedHeight(25) pip_up_down_layout.addWidget(up_btn) pip_up_down_layout.addWidget(dw_btn) string_label = QLabel() string_label.setText(label) string_label.setFixedWidth(210) btn = QtWidgets.QPushButton() btn.setFixedSize(20, 20) pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png") q_icon = QtGui.QIcon(pixmap_icon) btn.setIcon(q_icon) pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter) pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter) pip_main_layout.addWidget(string_label, Qt.AlignLeft) pip_main_layout.addWidget(btn, Qt.AlignVCenter) self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget) index = self.pip_widget_vbox_layout.indexOf(pip_main_widget) #print(index) # Create the corresponding settings widget and connect it settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(cat_position) self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.hide() self.stackedWidget_Settings.insertWidget(cat_position, settings_main_widget) #print("Read from pipeline entry " + str(cat)) #print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".") def show_settings(): # Set background color while widget is selected. Doesn't work because of theme? *TODO* p = pip_main_widget.palette() p.setColor(pip_main_widget.backgroundRole(), Qt.red) pip_main_widget.setPalette(p) self.stackedWidget_Settings.show() self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat)) self.settings_collapsable.setTitle(alg.get_name() + " Settings") self.remove_cat_alg_dropdown() # Create drop down for cats and algs self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget) #print(cat) #print(alg) self.set_cat_alg_dropdown(cat, alg) # Connect Button to remove step from pipeline def delete_button_clicked(): self.remove_pip_entry(pip_main_widget, settings_main_widget, cat) self.clickable(pixmap_label).connect(show_settings) self.clickable(string_label).connect(show_settings) btn.clicked.connect(delete_button_clicked) return (pip_main_widget, settings_main_widget) # https://wiki.python.org/moin/PyQt/Making%20non-clickable%20widgets%20clickable def clickable(self, widget): """ Convert any widget to a clickable widget. """ class Filter(QObject): clicked = pyqtSignal() def eventFilter(self, obj, event): if obj == widget: if event.type() == QEvent.MouseButtonPress: if obj.rect().contains(event.pos()): self.clicked.emit() # The developer can opt for .emit(obj) to get the object within the slot. return True return False filter = Filter(widget) widget.installEventFilter(filter) return filter.clicked
class NetworkChoiceLayout(object): def __init__(self, network: Network, config, wizard=False): self.network = network self.config = config self.protocol = None self.tor_proxy = None self.tabs = tabs = QTabWidget() server_tab = QWidget() proxy_tab = QWidget() blockchain_tab = QWidget() tabs.addTab(blockchain_tab, _('Overview')) tabs.addTab(server_tab, _('Server')) tabs.addTab(proxy_tab, _('Proxy')) # server tab grid = QGridLayout(server_tab) grid.setSpacing(8) self.server_host = QLineEdit() self.server_host.setFixedWidth(200) self.server_port = QLineEdit() self.server_port.setFixedWidth(60) self.autoconnect_cb = QCheckBox(_('Select server automatically')) self.autoconnect_cb.setEnabled(self.config.is_modifiable('auto_connect')) self.server_host.editingFinished.connect(self.set_server) self.server_port.editingFinished.connect(self.set_server) self.autoconnect_cb.clicked.connect(self.set_server) self.autoconnect_cb.clicked.connect(self.update) msg = ' '.join([ _("If auto-connect is enabled, Electrum will always use a server that is on the longest blockchain."), _("If it is disabled, you have to choose a server you want to use. Electrum will warn you if your server is lagging.") ]) grid.addWidget(self.autoconnect_cb, 0, 0, 1, 3) grid.addWidget(HelpButton(msg), 0, 4) grid.addWidget(QLabel(_('Server') + ':'), 1, 0) grid.addWidget(self.server_host, 1, 1, 1, 2) grid.addWidget(self.server_port, 1, 3) label = _('Server peers') if network.is_connected() else _('Default Servers') grid.addWidget(QLabel(label), 2, 0, 1, 5) self.servers_list = ServerListWidget(self) grid.addWidget(self.servers_list, 3, 0, 1, 5) # Proxy tab grid = QGridLayout(proxy_tab) grid.setSpacing(8) # proxy setting self.proxy_cb = QCheckBox(_('Use proxy')) self.proxy_cb.clicked.connect(self.check_disable_proxy) self.proxy_cb.clicked.connect(self.set_proxy) self.proxy_mode = QComboBox() self.proxy_mode.addItems(['SOCKS4', 'SOCKS5']) self.proxy_host = QLineEdit() self.proxy_host.setFixedWidth(200) self.proxy_port = QLineEdit() self.proxy_port.setFixedWidth(60) self.proxy_user = QLineEdit() self.proxy_user.setPlaceholderText(_("Proxy user")) self.proxy_password = QLineEdit() self.proxy_password.setPlaceholderText(_("Password")) self.proxy_password.setEchoMode(QLineEdit.Password) self.proxy_password.setFixedWidth(60) self.proxy_mode.currentIndexChanged.connect(self.set_proxy) self.proxy_host.editingFinished.connect(self.set_proxy) self.proxy_port.editingFinished.connect(self.set_proxy) self.proxy_user.editingFinished.connect(self.set_proxy) self.proxy_password.editingFinished.connect(self.set_proxy) self.proxy_mode.currentIndexChanged.connect(self.proxy_settings_changed) self.proxy_host.textEdited.connect(self.proxy_settings_changed) self.proxy_port.textEdited.connect(self.proxy_settings_changed) self.proxy_user.textEdited.connect(self.proxy_settings_changed) self.proxy_password.textEdited.connect(self.proxy_settings_changed) self.tor_cb = QCheckBox(_("Use Tor Proxy")) self.tor_cb.setIcon(read_QIcon("tor_logo.png")) self.tor_cb.hide() self.tor_cb.clicked.connect(self.use_tor_proxy) grid.addWidget(self.tor_cb, 1, 0, 1, 3) grid.addWidget(self.proxy_cb, 2, 0, 1, 3) grid.addWidget(HelpButton(_('Proxy settings apply to all connections: with Electrum servers, but also with third-party services.')), 2, 4) grid.addWidget(self.proxy_mode, 4, 1) grid.addWidget(self.proxy_host, 4, 2) grid.addWidget(self.proxy_port, 4, 3) grid.addWidget(self.proxy_user, 5, 2) grid.addWidget(self.proxy_password, 5, 3) grid.setRowStretch(7, 1) # Blockchain Tab grid = QGridLayout(blockchain_tab) msg = ' '.join([ _("Electrum connects to several nodes in order to download block headers and find out the longest blockchain."), _("This blockchain is used to verify the transactions sent by your transaction server.") ]) self.status_label = QLabel('') grid.addWidget(QLabel(_('Status') + ':'), 0, 0) grid.addWidget(self.status_label, 0, 1, 1, 3) grid.addWidget(HelpButton(msg), 0, 4) self.server_label = QLabel('') msg = _("Electrum sends your wallet addresses to a single server, in order to receive your transaction history.") grid.addWidget(QLabel(_('Server') + ':'), 1, 0) grid.addWidget(self.server_label, 1, 1, 1, 3) grid.addWidget(HelpButton(msg), 1, 4) self.height_label = QLabel('') msg = _('This is the height of your local copy of the blockchain.') grid.addWidget(QLabel(_('Blockchain') + ':'), 2, 0) grid.addWidget(self.height_label, 2, 1) grid.addWidget(HelpButton(msg), 2, 4) self.split_label = QLabel('') grid.addWidget(self.split_label, 3, 0, 1, 3) self.nodes_list_widget = NodesListWidget(self) grid.addWidget(self.nodes_list_widget, 5, 0, 1, 5) vbox = QVBoxLayout() vbox.addWidget(tabs) self.layout_ = vbox # tor detector self.td = td = TorDetector() td.found_proxy.connect(self.suggest_proxy) td.start() self.fill_in_proxy_settings() self.update() def check_disable_proxy(self, b): if not self.config.is_modifiable('proxy'): b = False for w in [self.proxy_mode, self.proxy_host, self.proxy_port, self.proxy_user, self.proxy_password]: w.setEnabled(b) def enable_set_server(self): if self.config.is_modifiable('server'): enabled = not self.autoconnect_cb.isChecked() self.server_host.setEnabled(enabled) self.server_port.setEnabled(enabled) self.servers_list.setEnabled(enabled) else: for w in [self.autoconnect_cb, self.server_host, self.server_port, self.servers_list]: w.setEnabled(False) def update(self): net_params = self.network.get_parameters() host, port, protocol = net_params.host, net_params.port, net_params.protocol proxy_config, auto_connect = net_params.proxy, net_params.auto_connect self.server_host.setText(host) self.server_port.setText(str(port)) self.autoconnect_cb.setChecked(auto_connect) interface = self.network.interface host = interface.host if interface else _('None') self.server_label.setText(host) self.set_protocol(protocol) self.servers = self.network.get_servers() self.servers_list.update(self.servers, self.protocol, self.tor_cb.isChecked()) self.enable_set_server() height_str = "%d "%(self.network.get_local_height()) + _('blocks') self.height_label.setText(height_str) n = len(self.network.get_interfaces()) status = _("Connected to {0} nodes.").format(n) if n else _("Not connected") self.status_label.setText(status) chains = self.network.get_blockchains() if len(chains) > 1: chain = self.network.blockchain() forkpoint = chain.get_max_forkpoint() name = chain.get_name() msg = _('Chain split detected at block {0}').format(forkpoint) + '\n' msg += (_('You are following branch') if auto_connect else _('Your server is on branch'))+ ' ' + name msg += ' (%d %s)' % (chain.get_branch_size(), _('blocks')) else: msg = '' self.split_label.setText(msg) self.nodes_list_widget.update(self.network) def fill_in_proxy_settings(self): proxy_config = self.network.get_parameters().proxy if not proxy_config: proxy_config = {"mode": "none", "host": "localhost", "port": "9050"} b = proxy_config.get('mode') != "none" self.check_disable_proxy(b) if b: self.proxy_cb.setChecked(True) self.proxy_mode.setCurrentIndex( self.proxy_mode.findText(str(proxy_config.get("mode").upper()))) self.proxy_host.setText(proxy_config.get("host")) self.proxy_port.setText(proxy_config.get("port")) self.proxy_user.setText(proxy_config.get("user", "")) self.proxy_password.setText(proxy_config.get("password", "")) def layout(self): return self.layout_ def set_protocol(self, protocol): if protocol != self.protocol: self.protocol = protocol def change_protocol(self, use_ssl): p = 's' if use_ssl else 't' host = self.server_host.text() pp = self.servers.get(host, constants.net.DEFAULT_PORTS) if p not in pp.keys(): p = list(pp.keys())[0] port = pp[p] self.server_host.setText(host) self.server_port.setText(port) self.set_protocol(p) self.set_server() def follow_branch(self, chain_id): self.network.run_from_another_thread(self.network.follow_chain_given_id(chain_id)) self.update() def follow_server(self, server): self.network.run_from_another_thread(self.network.follow_chain_given_server(server)) self.update() def server_changed(self, x): if x: self.change_server(str(x.text(0)), self.protocol) def change_server(self, host, protocol): pp = self.servers.get(host, constants.net.DEFAULT_PORTS) if protocol and protocol not in protocol_letters: protocol = None if protocol: port = pp.get(protocol) if port is None: protocol = None if not protocol: if 's' in pp.keys(): protocol = 's' port = pp.get(protocol) else: protocol = list(pp.keys())[0] port = pp.get(protocol) self.server_host.setText(host) self.server_port.setText(port) def accept(self): pass def set_server(self): net_params = self.network.get_parameters() net_params = net_params._replace(host=str(self.server_host.text()), port=str(self.server_port.text()), auto_connect=self.autoconnect_cb.isChecked()) self.network.run_from_another_thread(self.network.set_parameters(net_params)) def set_proxy(self): net_params = self.network.get_parameters() if self.proxy_cb.isChecked(): proxy = { 'mode':str(self.proxy_mode.currentText()).lower(), 'host':str(self.proxy_host.text()), 'port':str(self.proxy_port.text()), 'user':str(self.proxy_user.text()), 'password':str(self.proxy_password.text())} else: proxy = None self.tor_cb.setChecked(False) net_params = net_params._replace(proxy=proxy) self.network.run_from_another_thread(self.network.set_parameters(net_params)) def suggest_proxy(self, found_proxy): if found_proxy is None: self.tor_cb.hide() return self.tor_proxy = found_proxy self.tor_cb.setText("Use Tor proxy at port " + str(found_proxy[1])) if (self.proxy_cb.isChecked() and self.proxy_mode.currentIndex() == self.proxy_mode.findText('SOCKS5') and self.proxy_host.text() == "127.0.0.1" and self.proxy_port.text() == str(found_proxy[1])): self.tor_cb.setChecked(True) self.tor_cb.show() def use_tor_proxy(self, use_it): if not use_it: self.proxy_cb.setChecked(False) else: socks5_mode_index = self.proxy_mode.findText('SOCKS5') if socks5_mode_index == -1: _logger.info("can't find proxy_mode 'SOCKS5'") return self.proxy_mode.setCurrentIndex(socks5_mode_index) self.proxy_host.setText("127.0.0.1") self.proxy_port.setText(str(self.tor_proxy[1])) self.proxy_user.setText("") self.proxy_password.setText("") self.tor_cb.setChecked(True) self.proxy_cb.setChecked(True) self.check_disable_proxy(use_it) self.set_proxy() def proxy_settings_changed(self): self.tor_cb.setChecked(False)
class GalleryDialog(QWidget): """ A window for adding/modifying gallery. Pass a list of QModelIndexes to edit their data or pass a path to preset path """ gallery_queue = queue.Queue() SERIES = pyqtSignal(list) SERIES_EDIT = pyqtSignal(list, int) #gallery_list = [] # might want to extend this to allow mass gallery adding def __init__(self, parent=None, arg=None): super().__init__(parent, Qt.Dialog) self.setAttribute(Qt.WA_DeleteOnClose) self.parent_widget = parent log_d('Triggered Gallery Edit/Add Dialog') m_l = QVBoxLayout() self.main_layout = QVBoxLayout() dummy = QWidget(self) scroll_area = QScrollArea(self) scroll_area.setWidgetResizable(True) scroll_area.setFrameStyle(scroll_area.StyledPanel) dummy.setLayout(self.main_layout) scroll_area.setWidget(dummy) m_l.addWidget(scroll_area, 3) final_buttons = QHBoxLayout() final_buttons.setAlignment(Qt.AlignRight) m_l.addLayout(final_buttons) self.done = QPushButton("Done") self.done.setDefault(True) cancel = QPushButton("Cancel") final_buttons.addWidget(cancel) final_buttons.addWidget(self.done) def new_gallery(): self.setWindowTitle('Add a new gallery') self.newUI() self.commonUI() self.done.clicked.connect(self.accept) cancel.clicked.connect(self.reject) if arg: if isinstance(arg, list): self.setWindowTitle('Edit gallery') self.position = arg[0].row() for index in arg: gallery = index.data(Qt.UserRole+1) self.commonUI() self.setGallery(gallery) self.done.clicked.connect(self.accept_edit) cancel.clicked.connect(self.reject_edit) elif isinstance(arg, str): new_gallery() self.choose_dir(arg) else: new_gallery() log_d('GalleryDialog: Create UI: successful') #TODO: Implement a way to mass add galleries #IDEA: Extend dialog in a ScrollArea with more forms... self.setLayout(m_l) self.resize(500,560) frect = self.frameGeometry() frect.moveCenter(QDesktopWidget().availableGeometry().center()) self.move(frect.topLeft()) #self.setAttribute(Qt.WA_DeleteOnClose) def commonUI(self): f_web = QGroupBox("Metadata from the Web") f_web.setCheckable(False) self.main_layout.addWidget(f_web) web_main_layout = QVBoxLayout() web_layout = QHBoxLayout() web_main_layout.addLayout(web_layout) f_web.setLayout(web_main_layout) f_gallery = QGroupBox("Gallery Info") f_gallery.setCheckable(False) self.main_layout.addWidget(f_gallery) gallery_layout = QFormLayout() f_gallery.setLayout(gallery_layout) def basic_web(name): return QLabel(name), QLineEdit(), QPushButton("Get metadata"), QProgressBar() url_lbl, self.url_edit, url_btn, url_prog = basic_web("URL:") url_btn.clicked.connect(lambda: self.web_metadata(self.url_edit.text(), url_btn, url_prog)) url_prog.setTextVisible(False) url_prog.setMinimum(0) url_prog.setMaximum(0) web_layout.addWidget(url_lbl, 0, Qt.AlignLeft) web_layout.addWidget(self.url_edit, 0) web_layout.addWidget(url_btn, 0, Qt.AlignRight) web_layout.addWidget(url_prog, 0, Qt.AlignRight) self.url_edit.setPlaceholderText("Paste g.e-hentai/exhentai gallery url or just press the button.") url_prog.hide() self.title_edit = QLineEdit() self.author_edit = QLineEdit() author_completer = misc.GCompleter(self, False, True, False) author_completer.setCaseSensitivity(Qt.CaseInsensitive) self.author_edit.setCompleter(author_completer) self.descr_edit = QTextEdit() self.descr_edit.setFixedHeight(45) self.descr_edit.setAcceptRichText(True) self.lang_box = QComboBox() self.lang_box.addItems(["English", "Japanese", "Other"]) self.lang_box.setCurrentIndex(0) tags_l = QVBoxLayout() tag_info = misc.ClickedLabel("How do i write namespace & tags? (hover)", parent=self) tag_info.setToolTip("Ways to write tags:\n\nNormal tags:\ntag1, tag2, tag3\n\n"+ "Namespaced tags:\nns1:tag1, ns1:tag2\n\nNamespaced tags with one or more"+ " tags under same namespace:\nns1:[tag1, tag2, tag3], ns2:[tag1, tag2]\n\n"+ "Those three ways of writing namespace & tags can be combined freely.\n"+ "Tags are seperated by a comma, NOT whitespace.\nNamespaces will be capitalized while tags"+ " will be lowercased.") tag_info.setToolTipDuration(99999999) tags_l.addWidget(tag_info) self.tags_edit = misc.CompleterTextEdit() self.tags_edit.setCompleter(misc.GCompleter(self, False, False)) tags_l.addWidget(self.tags_edit, 3) self.tags_edit.setFixedHeight(70) self.tags_edit.setPlaceholderText("Press Tab to autocomplete (Ctrl + E to show popup)") self.type_box = QComboBox() self.type_box.addItems(["Manga", "Doujinshi", "Artist CG Sets", "Game CG Sets", "Western", "Image Sets", "Non-H", "Cosplay", "Other"]) self.type_box.setCurrentIndex(0) #self.type_box.currentIndexChanged[int].connect(self.doujin_show) #self.doujin_parent = QLineEdit() #self.doujin_parent.setVisible(False) self.status_box = QComboBox() self.status_box.addItems(["Unknown", "Ongoing", "Completed"]) self.status_box.setCurrentIndex(0) self.pub_edit = QDateEdit() self.pub_edit.setCalendarPopup(True) self.pub_edit.setDate(QDate.currentDate()) self.path_lbl = QLabel("") self.path_lbl.setWordWrap(True) link_layout = QHBoxLayout() self.link_lbl = QLabel("") self.link_lbl.setWordWrap(True) self.link_edit = QLineEdit() link_layout.addWidget(self.link_edit) link_layout.addWidget(self.link_lbl) self.link_edit.hide() self.link_btn = QPushButton("Modify") self.link_btn.setFixedWidth(50) self.link_btn2 = QPushButton("Set") self.link_btn2.setFixedWidth(40) self.link_btn.clicked.connect(self.link_modify) self.link_btn2.clicked.connect(self.link_set) link_layout.addWidget(self.link_btn) link_layout.addWidget(self.link_btn2) self.link_btn2.hide() gallery_layout.addRow("Title:", self.title_edit) gallery_layout.addRow("Author:", self.author_edit) gallery_layout.addRow("Description:", self.descr_edit) gallery_layout.addRow("Language:", self.lang_box) gallery_layout.addRow("Tags:", tags_l) gallery_layout.addRow("Type:", self.type_box) gallery_layout.addRow("Status:", self.status_box) gallery_layout.addRow("Publication Date:", self.pub_edit) gallery_layout.addRow("Path:", self.path_lbl) gallery_layout.addRow("Link:", link_layout) self.title_edit.setFocus() def _find_combobox_match(self, combobox, key, default): f_index = combobox.findText(key, Qt.MatchFixedString) try: combobox.setCurrentIndex(f_index) except: combobox.setCurrentIndex(default) def setGallery(self, gallery): "To be used for when editing a gallery" self.gallery = gallery self.url_edit.setText(gallery.link) self.title_edit.setText(gallery.title) self.author_edit.setText(gallery.artist) self.descr_edit.setText(gallery.info) self.tags_edit.setText(utils.tag_to_string(gallery.tags)) self._find_combobox_match(self.lang_box, gallery.language, 2) self._find_combobox_match(self.type_box, gallery.type, 0) self._find_combobox_match(self.status_box, gallery.status, 0) gallery_pub_date = "{}".format(gallery.pub_date).split(' ') try: self.gallery_time = datetime.strptime(gallery_pub_date[1], '%H:%M:%S').time() except IndexError: pass qdate_pub_date = QDate.fromString(gallery_pub_date[0], "yyyy-MM-dd") self.pub_edit.setDate(qdate_pub_date) self.link_lbl.setText(gallery.link) self.path_lbl.setText(gallery.path) def newUI(self): f_local = QGroupBox("Directory/Archive") f_local.setCheckable(False) self.main_layout.addWidget(f_local) local_layout = QHBoxLayout() f_local.setLayout(local_layout) choose_folder = QPushButton("From Directory") choose_folder.clicked.connect(lambda: self.choose_dir('f')) local_layout.addWidget(choose_folder) choose_archive = QPushButton("From Archive") choose_archive.clicked.connect(lambda: self.choose_dir('a')) local_layout.addWidget(choose_archive) self.file_exists_lbl = QLabel() local_layout.addWidget(self.file_exists_lbl) self.file_exists_lbl.hide() def choose_dir(self, mode): """ Pass which mode to open the folder explorer in: 'f': directory 'a': files Or pass a predefined path """ self.done.show() self.file_exists_lbl.hide() if mode == 'a': name = QFileDialog.getOpenFileName(self, 'Choose archive', filter=utils.FILE_FILTER) name = name[0] elif mode == 'f': name = QFileDialog.getExistingDirectory(self, 'Choose folder') elif mode: if os.path.exists(mode): name = mode else: return None if not name: return head, tail = os.path.split(name) name = os.path.join(head, tail) parsed = utils.title_parser(tail) self.title_edit.setText(parsed['title']) self.author_edit.setText(parsed['artist']) self.path_lbl.setText(name) l_i = self.lang_box.findText(parsed['language']) if l_i != -1: self.lang_box.setCurrentIndex(l_i) if gallerydb.GalleryDB.check_exists(name): self.file_exists_lbl.setText('<font color="red">Gallery already exists.</font>') self.file_exists_lbl.show() # check galleries gs = 1 if name.endswith(utils.ARCHIVE_FILES): gs = len(utils.check_archive(name)) elif os.path.isdir(name): g_dirs, g_archs = utils.recursive_gallery_check(name) gs = len(g_dirs) + len(g_archs) if gs == 0: self.file_exists_lbl.setText('<font color="red">Invalid gallery source.</font>') self.file_exists_lbl.show() self.done.hide() if app_constants.SUBFOLDER_AS_GALLERY: if gs > 1: self.file_exists_lbl.setText('<font color="red">More than one galleries detected in source! Use other methods to add.</font>') self.file_exists_lbl.show() self.done.hide() def check(self): if len(self.title_edit.text()) is 0: self.title_edit.setFocus() self.title_edit.setStyleSheet("border-style:outset;border-width:2px;border-color:red;") return False elif len(self.author_edit.text()) is 0: self.author_edit.setText("Unknown") if len(self.path_lbl.text()) == 0 or self.path_lbl.text() == 'No path specified': self.path_lbl.setStyleSheet("color:red") self.path_lbl.setText('No path specified') return False return True def set_chapters(self, gallery_object, add_to_model=True): path = gallery_object.path chap_container = gallerydb.ChaptersContainer(gallery_object) metafile = utils.GMetafile() try: log_d('Listing dir...') con = scandir.scandir(path) # list all folders in gallery dir log_i('Gallery source is a directory') log_d('Sorting') chapters = sorted([sub.path for sub in con if sub.is_dir() or sub.name.endswith(utils.ARCHIVE_FILES)]) #subfolders # if gallery has chapters divided into sub folders if len(chapters) != 0: log_d('Chapters divided in folders..') for ch in chapters: chap = chap_container.create_chapter() chap.title = utils.title_parser(ch)['title'] chap.path = os.path.join(path, ch) metafile.update(utils.GMetafile(chap.path)) chap.pages = len(list(scandir.scandir(chap.path))) else: #else assume that all images are in gallery folder chap = chap_container.create_chapter() chap.title = utils.title_parser(os.path.split(path)[1])['title'] chap.path = path metafile.update(utils.GMetafile(path)) chap.pages = len(list(scandir.scandir(path))) except NotADirectoryError: if path.endswith(utils.ARCHIVE_FILES): gallery_object.is_archive = 1 log_i("Gallery source is an archive") archive_g = sorted(utils.check_archive(path)) for g in archive_g: chap = chap_container.create_chapter() chap.path = g chap.in_archive = 1 metafile.update(utils.GMetafile(g, path)) arch = utils.ArchiveFile(path) chap.pages = len(arch.dir_contents(g)) arch.close() metafile.apply_gallery(gallery_object) if add_to_model: self.SERIES.emit([gallery_object]) log_d('Sent gallery to model') def reject(self): if self.check(): msgbox = QMessageBox() msgbox.setText("<font color='red'><b>Noo oniichan! You were about to add a new gallery.</b></font>") msgbox.setInformativeText("Do you really want to discard?") msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgbox.setDefaultButton(QMessageBox.No) if msgbox.exec() == QMessageBox.Yes: self.close() else: self.close() def web_metadata(self, url, btn_widget, pgr_widget): self.link_lbl.setText(url) f = fetch.Fetch() thread = QThread(self) thread.setObjectName('Gallerydialog web metadata') btn_widget.hide() pgr_widget.show() def status(stat): def do_hide(): try: pgr_widget.hide() btn_widget.show() except RuntimeError: pass if stat: do_hide() else: danger = """QProgressBar::chunk { background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 #FF0350,stop: 0.4999 #FF0020,stop: 0.5 #FF0019,stop: 1 #FF0000 ); border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; border: .px solid black;}""" pgr_widget.setStyleSheet(danger) QTimer.singleShot(3000, do_hide) f.deleteLater() def gallery_picker(gallery, title_url_list, q): self.parent_widget._web_metadata_picker(gallery, title_url_list, q, self) try: dummy_gallery = self.make_gallery(self.gallery) except AttributeError: dummy_gallery = self.make_gallery(gallerydb.Gallery(), False) if not dummy_gallery: status(False) return None dummy_gallery.link = url f.galleries = [dummy_gallery] f.moveToThread(thread) f.GALLERY_PICKER.connect(gallery_picker) f.GALLERY_EMITTER.connect(self.set_web_metadata) thread.started.connect(f.auto_web_metadata) thread.finished.connect(thread.deleteLater) f.FINISHED.connect(status) thread.start() def set_web_metadata(self, metadata): assert isinstance(metadata, gallerydb.Gallery) self.link_lbl.setText(metadata.link) self.title_edit.setText(metadata.title) self.author_edit.setText(metadata.artist) tags = "" lang = ['English', 'Japanese'] self._find_combobox_match(self.lang_box, metadata.language, 2) self.tags_edit.setText(utils.tag_to_string(metadata.tags)) pub_string = "{}".format(metadata.pub_date) pub_date = QDate.fromString(pub_string.split()[0], "yyyy-MM-dd") self.pub_edit.setDate(pub_date) self._find_combobox_match(self.type_box, metadata.type, 0) def make_gallery(self, new_gallery, add_to_model=True, new=False): if self.check(): new_gallery.title = self.title_edit.text() log_d('Adding gallery title') new_gallery.artist = self.author_edit.text() log_d('Adding gallery artist') log_d('Adding gallery path') if new and app_constants.MOVE_IMPORTED_GALLERIES: app_constants.OVERRIDE_MONITOR = True new_gallery.path = utils.move_files(self.path_lbl.text()) else: new_gallery.path = self.path_lbl.text() new_gallery.info = self.descr_edit.toPlainText() log_d('Adding gallery descr') new_gallery.type = self.type_box.currentText() log_d('Adding gallery type') new_gallery.language = self.lang_box.currentText() log_d('Adding gallery lang') new_gallery.status = self.status_box.currentText() log_d('Adding gallery status') new_gallery.tags = utils.tag_to_dict(self.tags_edit.toPlainText()) log_d('Adding gallery: tagging to dict') qpub_d = self.pub_edit.date().toString("ddMMyyyy") dpub_d = datetime.strptime(qpub_d, "%d%m%Y").date() try: d_t = self.gallery_time except AttributeError: d_t = datetime.now().time().replace(microsecond=0) dpub_d = datetime.combine(dpub_d, d_t) new_gallery.pub_date = dpub_d log_d('Adding gallery pub date') new_gallery.link = self.link_lbl.text() log_d('Adding gallery link') if not new_gallery.chapters: log_d('Starting chapters') thread = threading.Thread(target=self.set_chapters, args=(new_gallery,add_to_model), daemon=True) thread.start() thread.join() log_d('Finished chapters') return new_gallery def link_set(self): t = self.link_edit.text() self.link_edit.hide() self.link_lbl.show() self.link_lbl.setText(t) self.link_btn2.hide() self.link_btn.show() def link_modify(self): t = self.link_lbl.text() self.link_lbl.hide() self.link_edit.show() self.link_edit.setText(t) self.link_btn.hide() self.link_btn2.show() def accept(self): new_gallery = self.make_gallery(gallerydb.Gallery(), new=True) if new_gallery: self.close() def accept_edit(self): new_gallery = self.make_gallery(self.gallery) #for ser in self.gallery: if new_gallery: self.SERIES_EDIT.emit([new_gallery], self.position) self.close() def reject_edit(self): self.close()
class GeneralExecution(QWidget): """General Execution widget class""" def __init__(self, parent): super(GeneralExecution, self).__init__() self._preferences = parent vbox = QVBoxLayout(self) groupExecution = QGroupBox(translations.TR_WORKSPACE_PROJECTS) grid = QVBoxLayout(groupExecution) #Python Path hPath = QHBoxLayout() self._txtPythonPath = QLineEdit() self._btnPythonPath = QPushButton(QIcon(':img/open'), '') self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self._txtPythonPath.setCompleter(self.completer) hPath.addWidget(QLabel(translations.TR_SELECT_PYTHON_EXEC)) hPath.addWidget(self._txtPythonPath) hPath.addWidget(self._btnPythonPath) grid.addLayout(hPath) #Python Miscellaneous Execution options self.check_B = QCheckBox(translations.TR_SELECT_EXEC_OPTION_B) self.check_d = QCheckBox(translations.TR_SELECT_EXEC_OPTION_D) self.check_E = QCheckBox(translations.TR_SELECT_EXEC_OPTION_E) self.check_O = QCheckBox(translations.TR_SELECT_EXEC_OPTION_O) self.check_OO = QCheckBox(translations.TR_SELECT_EXEC_OPTION_OO) self.check_Q = QCheckBox(translations.TR_SELECT_EXEC_OPTION_Q) self.comboDivision = QComboBox() self.comboDivision.addItems(['old', 'new', 'warn', 'warnall']) self.check_s = QCheckBox(translations.TR_SELECT_EXEC_OPTION_s) self.check_S = QCheckBox(translations.TR_SELECT_EXEC_OPTION_S) self.check_t = QCheckBox(translations.TR_SELECT_EXEC_OPTION_T) self.check_tt = QCheckBox(translations.TR_SELECT_EXEC_OPTION_TT) self.check_v = QCheckBox(translations.TR_SELECT_EXEC_OPTION_V) self.check_W = QCheckBox(translations.TR_SELECT_EXEC_OPTION_W) self.comboWarning = QComboBox() self.comboWarning.addItems( ['default', 'ignore', 'all', 'module', 'once', 'error']) self.check_x = QCheckBox(translations.TR_SELECT_EXEC_OPTION_X) self.check_3 = QCheckBox(translations.TR_SELECT_EXEC_OPTION_3) grid.addWidget(self.check_B) grid.addWidget(self.check_d) grid.addWidget(self.check_E) grid.addWidget(self.check_O) grid.addWidget(self.check_OO) hDiv = QHBoxLayout() hDiv.addWidget(self.check_Q) hDiv.addWidget(self.comboDivision) grid.addLayout(hDiv) grid.addWidget(self.check_s) grid.addWidget(self.check_S) grid.addWidget(self.check_t) grid.addWidget(self.check_tt) grid.addWidget(self.check_v) hWarn = QHBoxLayout() hWarn.addWidget(self.check_W) hWarn.addWidget(self.comboWarning) grid.addLayout(hWarn) grid.addWidget(self.check_x) grid.addWidget(self.check_3) #Settings self._txtPythonPath.setText(settings.PYTHON_EXEC) options = settings.EXECUTION_OPTIONS.split() if '-B' in options: self.check_B.setChecked(True) if '-d' in options: self.check_d.setChecked(True) if '-E' in options: self.check_E.setChecked(True) if '-O' in options: self.check_O.setChecked(True) if '-OO' in options: self.check_OO.setChecked(True) if settings.EXECUTION_OPTIONS.find('-Q') > -1: self.check_Q.setChecked(True) index = settings.EXECUTION_OPTIONS.find('-Q') opt = settings.EXECUTION_OPTIONS[index + 2:].split(' ', 1)[0] index = self.comboDivision.findText(opt) self.comboDivision.setCurrentIndex(index) if '-s' in options: self.check_s.setChecked(True) if '-S' in options: self.check_S.setChecked(True) if '-t' in options: self.check_t.setChecked(True) if '-tt' in options: self.check_tt.setChecked(True) if '-v' in options: self.check_v.setChecked(True) if settings.EXECUTION_OPTIONS.find('-W') > -1: self.check_W.setChecked(True) index = settings.EXECUTION_OPTIONS.find('-W') opt = settings.EXECUTION_OPTIONS[index + 2:].split(' ', 1)[0] index = self.comboWarning.findText(opt) self.comboWarning.setCurrentIndex(index) if '-x' in options: self.check_x.setChecked(True) if '-3' in options: self.check_3.setChecked(True) vbox.addWidget(groupExecution) #Signals self._btnPythonPath.clicked['bool'].connect(self._load_python_path) self._preferences.savePreferences.connect(self.save) def _load_python_path(self): """Ask the user for a Python Path""" path = QFileDialog.getOpenFileName(self, translations.TR_SELECT_SELECT_PYTHON_EXEC) if path: self._txtPythonPath.setText(path) def save(self): """Save all the Execution Preferences""" qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('execution') qsettings.setValue('pythonPath', self._txtPythonPath.text()) settings.PYTHON_PATH = self._txtPythonPath.text() options = '' if self.check_B.isChecked(): options += ' -B' if self.check_d.isChecked(): options += ' -d' if self.check_E.isChecked(): options += ' -E' if self.check_O.isChecked(): options += ' -O' if self.check_OO.isChecked(): options += ' -OO' if self.check_Q.isChecked(): options += ' -Q' + self.comboDivision.currentText() if self.check_s.isChecked(): options += ' -s' if self.check_S.isChecked(): options += ' -S' if self.check_t.isChecked(): options += ' -t' if self.check_tt.isChecked(): options += ' -tt' if self.check_v.isChecked(): options += ' -v' if self.check_W.isChecked(): options += ' -W' + self.comboWarning.currentText() if self.check_x.isChecked(): options += ' -x' if self.check_3.isChecked(): options += ' -3' settings.EXECUTION_OPTIONS = options qsettings.setValue('executionOptions', options) qsettings.endGroup() qsettings.endGroup()
class Interface(QWidget): """Interface widget class.""" def __init__(self, parent): super(Interface, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) self.toolbar_settings = settings.TOOLBAR_ITEMS groupBoxExplorer = QGroupBox( translations.TR_PREFERENCES_INTERFACE_EXPLORER_PANEL) group_theme = QGroupBox( translations.TR_PREFERENCES_THEME) group_hdpi = QGroupBox(translations.TR_PREFERENCES_SCREEN_RESOLUTION) # groupBoxToolbar = QGroupBox( # translations.TR_PREFERENCES_INTERFACE_TOOLBAR_CUSTOMIZATION) groupBoxLang = QGroupBox( translations.TR_PREFERENCES_INTERFACE_LANGUAGE) # Explorers vboxExplorer = QVBoxLayout(groupBoxExplorer) self._checkProjectExplorer = QCheckBox( translations.TR_PREFERENCES_SHOW_EXPLORER) self._checkSymbols = QCheckBox( translations.TR_PREFERENCES_SHOW_SYMBOLS) self._checkWebInspetor = QCheckBox( translations.TR_PREFERENCES_SHOW_WEB_INSPECTOR) self._checkFileErrors = QCheckBox( translations.TR_PREFERENCES_SHOW_FILE_ERRORS) self._checkMigrationTips = QCheckBox( translations.TR_PREFERENCES_SHOW_MIGRATION) vboxExplorer.addWidget(self._checkProjectExplorer) vboxExplorer.addWidget(self._checkSymbols) vboxExplorer.addWidget(self._checkWebInspetor) vboxExplorer.addWidget(self._checkFileErrors) vboxExplorer.addWidget(self._checkMigrationTips) # Theme vbox_theme = QVBoxLayout(group_theme) hbox = QHBoxLayout() hbox.addWidget(QLabel(translations.TR_PREFERENCES_NINJA_THEME)) self._combobox_themes = QComboBox() # self._combobox_themes.addItems(theme.available_theme_names()) self._combobox_themes.setCurrentText(settings.NINJA_SKIN) hbox.addWidget(self._combobox_themes) vbox_theme.addLayout(hbox) vbox_theme.addWidget( QLabel(translations.TR_PREFERENCES_REQUIRES_RESTART)) # HDPI hbox = QHBoxLayout(group_hdpi) self._combo_resolution = QComboBox() self._combo_resolution.addItems([ translations.TR_PREFERENCES_SCREEN_NORMAL, translations.TR_PREFERENCES_SCREEN_AUTO_HDPI, translations.TR_PREFERENCES_SCREEN_CUSTOM_HDPI ]) self._combo_resolution.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) hbox.addWidget(self._combo_resolution) self._line_custom_hdpi = QLineEdit() self._line_custom_hdpi.setPlaceholderText("1.5") hbox.addWidget(self._line_custom_hdpi) #GUI - Toolbar #vbox_toolbar = QVBoxLayout(groupBoxToolbar) #hbox_select_items = QHBoxLayout() #label_toolbar = QLabel(translations.TR_PREFERENCES_TOOLBAR_ITEMS) #label_toolbar.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) #hbox_select_items.addWidget(label_toolbar) #self._comboToolbarItems = QComboBox() #self._load_combo_data(self._comboToolbarItems) #self._btnItemAdd = QPushButton(QIcon(":img/add"), '') #self._btnItemAdd.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) #self._btnItemAdd.setIconSize(QSize(16, 16)) #self._btnItemRemove = QPushButton(QIcon(':img/delete'), '') #self._btnItemRemove.setIconSize(QSize(16, 16)) #self._btnDefaultItems = QPushButton( #translations.TR_PREFERENCES_TOOLBAR_DEFAULT) #self._btnDefaultItems.setSizePolicy(QSizePolicy.Fixed, #QSizePolicy.Fixed) #self._btnItemRemove.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) #hbox_select_items.addWidget(self._comboToolbarItems) #hbox_select_items.addWidget(self._btnItemAdd) #hbox_select_items.addWidget(self._btnItemRemove) #hbox_select_items.addWidget(self._btnDefaultItems) #vbox_toolbar.addLayout(hbox_select_items) #self._toolbar_items = QToolBar() #self._toolbar_items.setObjectName("custom") #self._toolbar_items.setToolButtonStyle(Qt.ToolButtonIconOnly) #self._load_toolbar() #vbox_toolbar.addWidget(self._toolbar_items) #vbox_toolbar.addWidget(QLabel( #translations.TR_PREFERENCES_TOOLBAR_CONFIG_HELP)) # Language vboxLanguage = QVBoxLayout(groupBoxLang) vboxLanguage.addWidget(QLabel( translations.TR_PREFERENCES_SELECT_LANGUAGE)) self._comboLang = QComboBox() self._comboLang.setEnabled(False) vboxLanguage.addWidget(self._comboLang) vboxLanguage.addWidget(QLabel( translations.TR_PREFERENCES_REQUIRES_RESTART)) # Load Languages self._load_langs() # Settings self._checkProjectExplorer.setChecked( settings.SHOW_PROJECT_EXPLORER) self._checkSymbols.setChecked(settings.SHOW_SYMBOLS_LIST) self._checkWebInspetor.setChecked(settings.SHOW_WEB_INSPECTOR) self._checkFileErrors.setChecked(settings.SHOW_ERRORS_LIST) self._checkMigrationTips.setChecked(settings.SHOW_MIGRATION_LIST) self._line_custom_hdpi.setText(settings.CUSTOM_SCREEN_RESOLUTION) index = 0 if settings.HDPI: index = 1 elif settings.CUSTOM_SCREEN_RESOLUTION: index = 2 self._combo_resolution.setCurrentIndex(index) vbox.addWidget(groupBoxExplorer) vbox.addWidget(group_theme) vbox.addWidget(group_hdpi) # vbox.addWidget(groupBoxToolbar) vbox.addWidget(groupBoxLang) vbox.addStretch(1) # Signals # self.connect(self._btnItemAdd, SIGNAL("clicked()"), # # self.toolbar_item_added) # self.connect(self._btnItemRemove, SIGNAL("clicked()"), # # self.toolbar_item_removed) # self.connect(self._btnDefaultItems, SIGNAL("clicked()"), # # self.toolbar_items_default) self._combo_resolution.currentIndexChanged.connect( self._on_resolution_changed) self._preferences.savePreferences.connect(self.save) def _on_resolution_changed(self, index): enabled = False if index == 2: enabled = True self._line_custom_hdpi.setEnabled(enabled) #def toolbar_item_added(self): #data = self._comboToolbarItems.itemData( #self._comboToolbarItems.currentIndex()) #if data not in self.toolbar_settings or data == 'separator': #selected = self.actionGroup.checkedAction() #if selected is None: #self.toolbar_settings.append(data) #else: #dataAction = selected.data() #self.toolbar_settings.insert( #self.toolbar_settings.index(dataAction) + 1, data) #self._load_toolbar() ## def toolbar_item_removed(self): #data = self._comboToolbarItems.itemData( #self._comboToolbarItems.currentIndex()) #if data in self.toolbar_settings and data != 'separator': #self.toolbar_settings.pop(self.toolbar_settings.index(data)) #self._load_toolbar() #elif data == 'separator': #self.toolbar_settings.reverse() #self.toolbar_settings.pop(self.toolbar_settings.index(data)) #self.toolbar_settings.reverse() #self._load_toolbar() ## def toolbar_items_default(self): #self.toolbar_settings = settings.TOOLBAR_ITEMS_DEFAULT #self._load_toolbar() ## def _load_combo_data(self, combo): #self.toolbar_items = { #'separator': [QIcon(':img/separator'), 'Add Separtor'], #'new-file': [QIcon(resources.IMAGES['new']), self.tr('New File')], #'new-project': [QIcon(resources.IMAGES['newProj']), #self.tr('New Project')], #'save-file': [QIcon(resources.IMAGES['save']), #self.tr('Save File')], #'save-as': [QIcon(resources.IMAGES['saveAs']), self.tr('Save As')], #'save-all': [QIcon(resources.IMAGES['saveAll']), #self.tr('Save All')], #'save-project': [QIcon(resources.IMAGES['saveAll']), #self.tr('Save Project')], #'reload-file': [QIcon(resources.IMAGES['reload-file']), #self.tr('Reload File')], #'open-file': [QIcon(resources.IMAGES['open']), #self.tr('Open File')], #'open-project': [QIcon(resources.IMAGES['openProj']), #self.tr('Open Project')], #'activate-profile': [QIcon(resources.IMAGES['activate-profile']), #self.tr('Activate Profile')], #'deactivate-profile': #[QIcon(resources.IMAGES['deactivate-profile']), #self.tr('Deactivate Profile')], #'print-file': [QIcon(resources.IMAGES['print']), #self.tr('Print File')], #'close-file': #[self.style().standardIcon(QStyle.SP_DialogCloseButton), #self.tr('Close File')], #'close-projects': #[self.style().standardIcon(QStyle.SP_DialogCloseButton), #self.tr('Close Projects')], #'undo': [QIcon(resources.IMAGES['undo']), self.tr('Undo')], #'redo': [QIcon(resources.IMAGES['redo']), self.tr('Redo')], #'cut': [QIcon(resources.IMAGES['cut']), self.tr('Cut')], #'copy': [QIcon(resources.IMAGES['copy']), self.tr('Copy')], #'paste': [QIcon(resources.IMAGES['paste']), self.tr('Paste')], #'find': [QIcon(resources.IMAGES['find']), self.tr('Find')], #'find-replace': [QIcon(resources.IMAGES['findReplace']), #self.tr('Find/Replace')], #'find-files': [QIcon(resources.IMAGES['find']), #self.tr('Find In files')], #'code-locator': [QIcon(resources.IMAGES['locator']), #self.tr('Code Locator')], #'splith': [QIcon(resources.IMAGES['splitH']), #self.tr('Split Horizontally')], #'splitv': [QIcon(resources.IMAGES['splitV']), #self.tr('Split Vertically')], #'follow-mode': [QIcon(resources.IMAGES['follow']), #self.tr('Follow Mode')], #'zoom-in': [QIcon(resources.IMAGES['zoom-in']), self.tr('Zoom In')], #'zoom-out': [QIcon(resources.IMAGES['zoom-out']), #self.tr('Zoom Out')], #'indent-more': [QIcon(resources.IMAGES['indent-more']), #self.tr('Indent More')], #'indent-less': [QIcon(resources.IMAGES['indent-less']), #self.tr('Indent Less')], #'comment': [QIcon(resources.IMAGES['comment-code']), #self.tr('Comment')], #'uncomment': [QIcon(resources.IMAGES['uncomment-code']), #self.tr('Uncomment')], #'go-to-definition': [QIcon(resources.IMAGES['go-to-definition']), #self.tr('Go To Definition')], #'insert-import': [QIcon(resources.IMAGES['insert-import']), #self.tr('Insert Import')], #'run-project': [QIcon(resources.IMAGES['play']), 'Run Project'], #'run-file': [QIcon(resources.IMAGES['file-run']), 'Run File'], #'stop': [QIcon(resources.IMAGES['stop']), 'Stop'], #'preview-web': [QIcon(resources.IMAGES['preview-web']), #self.tr('Preview Web')]} #for item in self.toolbar_items: #combo.addItem(self.toolbar_items[item][0], #self.toolbar_items[item][1], item) #combo.model().sort(0) ## def _load_toolbar(self): #pass ##self._toolbar_items.clear() ##self.actionGroup = QActionGroup(self) ##self.actionGroup.setExclusive(True) ##for item in self.toolbar_settings: ##if item == 'separator': ##self._toolbar_items.addSeparator() ##else: ##action = self._toolbar_items.addAction( ##self.toolbar_items[item][0], self.toolbar_items[item][1]) ##action.setData(item) ##action.setCheckable(True) ##self.actionGroup.addAction(action) def _load_langs(self): langs = file_manager.get_files_from_folder( resources.LANGS, '.qm') self._languages = ['English'] + \ [file_manager.get_module_name(lang) for lang in langs] self._comboLang.addItems(self._languages) if(self._comboLang.count() > 1): self._comboLang.setEnabled(True) if settings.LANGUAGE: index = self._comboLang.findText(settings.LANGUAGE) else: index = 0 self._comboLang.setCurrentIndex(index) def save(self): qsettings = IDE.ninja_settings() qsettings.beginGroup("ide") qsettings.beginGroup("interface") ninja_theme = self._combobox_themes.currentText() settings.NINJA_SKIN = ninja_theme qsettings.setValue("skin", settings.NINJA_SKIN) settings.SHOW_PROJECT_EXPLORER = self._checkProjectExplorer.isChecked() qsettings.setValue("showProjectExplorer", settings.SHOW_PROJECT_EXPLORER) settings.SHOW_SYMBOLS_LIST = self._checkSymbols.isChecked() qsettings.setValue("showSymbolsList", settings.SHOW_SYMBOLS_LIST) if self._line_custom_hdpi.isEnabled(): screen_resolution = self._line_custom_hdpi.text().strip() settings.CUSTOM_SCREEN_RESOLUTION = screen_resolution else: settings.HDPI = bool(self._combo_resolution.currentIndex()) qsettings.setValue("autoHdpi", settings.HDPI) settings.CUSTOM_SCREEN_RESOLUTION = "" qsettings.setValue("customScreenResolution", settings.CUSTOM_SCREEN_RESOLUTION) qsettings.endGroup() qsettings.endGroup()