def get_folder_filepath( parent, message: str, *, show_files: bool = True, directory: str = '', exists: bool = True, native: bool = False, ) -> Path or None: options = QFileDialog.DontResolveSymlinks if not native: options |= QFileDialog.DontUseNativeDialog if not show_files: options |= QFileDialog.ShowDirsOnly dialog = QFileDialog(parent, caption=message, directory=directory) dialog.setFileMode(QFileDialog.Directory) dialog.setOptions(options) if not exists: dialog.setAcceptMode(QFileDialog.AcceptSave) if dialog.exec_() == QFileDialog.Accepted: folder_path = dialog.selectedFiles()[0] if folder_path: return Path(folder_path)
def Download(self): from PyQt5.QtWidgets import QFileDialog, QDialog try: opt = QtWidgets.QFileDialog.Options() opt |= QtWidgets.QFileDialog.DontUseSheet dialog = QFileDialog() dialog.setOptions(opt) dialog.setDirectory(self.userDPath) path, _ = QtWidgets.QFileDialog.getSaveFileName( None, "Where to Download?", "MyChangeAvatar.png", "PNG (*.png)", options=opt, ) if path: import shutil shutil.copyfile( self.AppSettingDir + "prxUserMeta\\MegaSRX\\metaprodata\\" + self.user[self.currentUserCounter] + ".png", path, ) except Exception as e: self.logit(str(e), "error")
def readMap(filename=None): """ Import alternate map file. """ if filename is None: fd = QFileDialog(None, "Load map file") fd.setLabelText(QFileDialog.Accept, "Import") fd.setNameFilters(["Map Files (*.txt)", "All Files (*)"]) fd.setOptions(QFileDialog.DontUseNativeDialog) fd.setViewMode(QFileDialog.List) fd.setFileMode(QFileDialog.ExistingFile) if fd.exec(): fileNames = fd.selectedFiles() filename = fileNames[0] else: pass numlines = sum(1 for line in open(filename)) if numlines < 2: print('Map file is empty.') return else: print('Map has ', numlines, ' lines.') # read the first line - target coords in HH:MM:SS.SS, DD:MM:SS.SS file = open(filename) line = file.readline() if len(line.split()) != 6: print('File is not a map file.') return file.close() mapListPath = filename numMapPoints = numlines - 1 return numMapPoints, mapListPath
def open_file_dialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog options |= QFileDialog.ShowDirsOnly dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.DirectoryOnly) dialog.setOptions(options) file_view = dialog.findChild(QListView, 'listView') # to make it possible to select multiple directories: if file_view: file_view.setSelectionMode(QAbstractItemView.ExtendedSelection) f_tree_view = dialog.findChild(QTreeView) if f_tree_view: f_tree_view.setSelectionMode(QAbstractItemView.ExtendedSelection) if dialog.exec(): paths = dialog.selectedFiles() for patient_data_directory in paths: patient_identifier = os.path.basename(patient_data_directory) if patient_identifier not in self.patient_data_sets: dp_file_path = os.path.join(patient_data_directory, 'result_images', 'exported_data', 'diffusion_parameters.mat') if os.path.exists(dp_file_path): data = loadmat(dp_file_path) self.load_data(patient_identifier, data) else: error_dialog = QtWidgets.QErrorMessage() error_dialog.showMessage( f'File path error: {patient_data_directory} does not contain diffusion ' f'parameters') error_dialog.exec_()
def writeSct(sctPars, sctfile): """ Write a *.sct file from a dictionary. """ fd = QFileDialog(None, "Save updated .sct file") fd.setLabelText(QFileDialog.Accept, "Export as") fd.setNameFilters(["Scan description (*.sct)", "All Files (*)"]) fd.setOptions(QFileDialog.DontUseNativeDialog) fd.setViewMode(QFileDialog.List) fd.selectFile(sctfile) if fd.exec(): #fd.getSaveFileName(directory=sctfile) filenames = fd.selectedFiles() filename = filenames[0] if filename[-4:] != '.sct': filename += '.sct' print("Exporting scan description to file: ", filename) with io.open(filename, mode='w') as f: for key in sctPars.keys(): if sctPars[key] != "": #print(sctPars[key]) f.write("{0:25s} #{1:s}\n".format(sctPars[key], key.upper())) print('File ' + filename + ' exported.') msg = "File " + filename + ' exported.\n' else: msg = 'Updated .sct file not saved.\n' return msg
def write_csv(self): dialog = QFileDialog(self, 'Write csv file', '.', '*.csv') dialog.setDefaultSuffix('csv') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') f = self.dut.freq o = np.interp(f, self.open.freq, self.open.data, period=self.open.period) s = np.interp(f, self.short.freq, self.short.data, period=self.short.period) l = np.interp(f, self.load.freq, self.load.data, period=self.load.period) d = self.dut.data fh.write( 'frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n' ) for i in range(f.size): fh.write( '0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i])) fh.close()
def getSaveFileNameWithSuffix(parent, caption, directory, filter, options=None, selectedFilter=None, defaultSuffix=None): """ A reimplemented version of QFileDialog.getSaveFileName() because we would like to make use of the QFileDialog.defaultSuffix property that getSaveFileName() does not let us adjust. Note: knowing the selected filter is not an invitation to change the chosen filename later. """ dialog = QFileDialog(parent=parent, caption=caption, directory=directory, filter=filter) if options: dialog.setOptions(options) if defaultSuffix: dialog.setDefaultSuffix(defaultSuffix) dialog.setFileMode(QFileDialog.AnyFile) if hasattr(dialog, 'setSupportedSchemes'): # Pre-Qt5.6 lacks this. dialog.setSupportedSchemes(("file", )) dialog.setAcceptMode(QFileDialog.AcceptSave) if selectedFilter: dialog.selectNameFilter(selectedFilter) if (dialog.exec() == QFileDialog.Accepted): return dialog.selectedFiles()[0], dialog.selectedNameFilter() return None, None
def chooseFiles(self, mode, oldFiles, acceptedMimeTypes): #Format acceptedMimeTypes nameFiltersString = "" for x in acceptedMimeTypes: nameFiltersString += "*" + x + " " uploadDialog = QFileDialog() if (args.downloadPath): uploadDialog.setDirectory(args.downloadPath) uploadDialog.setNameFilters([nameFiltersString]) uploadDialog.setFileMode(QFileDialog.ExistingFile) uploadDialog.setAcceptMode(QFileDialog.AcceptOpen) options = QFileDialog.Options() options |= QFileDialog.ReadOnly options |= QFileDialog.DontUseNativeDialog uploadDialog.setOptions(options) if uploadDialog.exec_(): fileName = uploadDialog.selectedFiles() return fileName return [""]
def on_saveButton_clicked(self): if PATH.IS_SCREEN: DIR = PATH.SCREENDIR else: DIR = PATH.PANELDIR dialog = QFileDialog(self) options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog dialog.setOptions(options) dialog.setDirectory(DIR) dialog.setFileMode(QFileDialog.AnyFile) dialog.setNameFilter("style files (*.qss *.style);;All files (*.*)") dialog.setWindowTitle('Save StyleSheet') dialog.setLabelText(QFileDialog.Accept, "Save") # sidebar links urls = [] urls.append(QUrl.fromLocalFile(os.path.expanduser('~'))) urls.append(QUrl.fromLocalFile(DIR)) urls.append( QUrl.fromLocalFile( os.path.join(os.getcwd(), 'qtvcp/screens', PATH.BASENAME))) dialog.setSidebarUrls(urls) result = dialog.exec_() if result: fileName = dialog.selectedFiles()[0] self.saveStyleSheet(fileName)
def FileDialog(directory='', forOpen=True, fmt='', isFolder=False): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog options |= QFileDialog.DontUseCustomDirectoryIcons dialog = QFileDialog() dialog.setOptions(options) dialog.setFilter(dialog.filter() | QtCore.QDir.Hidden) # ARE WE TALKING ABOUT FILES OR FOLDERS if isFolder: dialog.setFileMode(QFileDialog.DirectoryOnly) else: dialog.setFileMode(QFileDialog.AnyFile) # OPENING OR SAVING dialog.setAcceptMode(QFileDialog.AcceptOpen) if forOpen else dialog.setAcceptMode(QFileDialog.AcceptSave) # SET FORMAT, IF SPECIFIED if fmt != '' and isFolder is False: dialog.setDefaultSuffix(fmt) dialog.setNameFilters([f'{fmt} (*.{fmt})']) # SET THE STARTING DIRECTORY if directory != '': dialog.setDirectory(str(directory)) else: dialog.setDirectory(str(ROOT_DIR)) if dialog.exec_() == QDialog.Accepted: path = dialog.selectedFiles()[0] # returns a list return path else: return ''
def conv_save_pressed(P, W): head = _translate('HandlerClass', 'Save Error') with open(P.fNgc, 'r') as inFile: for line in inFile: if '(new conversational file)' in line: msg0 = _translate('HandlerClass', 'An empty file cannot be saved') P.dialog_show_ok(QMessageBox.Warning, '{}'.format(head), '{}\n'.format(msg0)) return P.vkb_show() dlg = QFileDialog(W) dlg.setOptions(QFileDialog.DontUseNativeDialog) dlg.setAcceptMode(QFileDialog.AcceptSave) dlg.setNameFilters(['G-Code Files (*.ngc *.nc *.tap)', 'All Files (*)']) dlg.setDefaultSuffix('ngc') dlg.setDirectory(P.programPrefix) name = '' if dlg.exec_(): name = dlg.selectedFiles()[0] if name: COPY(P.fNgc, name) W.conv_save.setEnabled(False) conv_enable_tabs(P, W) P.vkb_show(True)
def saveRotatedFits(self, name_orig): """ Save the downloaded FITS image """ filename, file_extension = os.path.splitext(name_orig) #fileroot = os.path.basename(filename) #print('file root is ', fileroot) print('Saving ',filename+'_NE.fits') # Dialog to save file fd = QFileDialog() fd.setLabelText(QFileDialog.Accept, "Save as") fd.setNameFilters(["Fits Files (*.fits)","All Files (*)"]) fd.setOptions(QFileDialog.DontUseNativeDialog) fd.setViewMode(QFileDialog.List) fd.selectFile(filename+'_NE.fits') if (fd.exec()): fileName = fd.selectedFiles() outfile = fileName[0] filename, file_extension = os.path.splitext(outfile) # basename = os.path.basename(filename) # Primary header image = self.data wcs = self.wcs header = wcs.to_header() header.remove('WCSAXES') header['INSTRUME'] = (self.source, 'Instrument') hdu = fits.PrimaryHDU(image) hdu.header.extend(header) hdul = fits.HDUList([hdu]) hdul.writeto(outfile,overwrite=True) # clobber true allows rewriting hdul.close()
def openLocalCube(self): """ Open local spectral cube.""" # Open a dialog fd = QFileDialog() fd.setLabelText(QFileDialog.Accept, "Import") fd.setNameFilters(["Fits Files (*.fits)", "All Files (*)"]) fd.setOptions(QFileDialog.DontUseNativeDialog) fd.setViewMode(QFileDialog.List) fd.setFileMode(QFileDialog.ExistingFile) if (fd.exec()): filenames = fd.selectedFiles() cube_file = filenames[0] print("File selected is: ", filenames[0]) try: print('opening ', cube_file) self.data = specCube(cube_file) self.wcs = self.data.wcs # Check if coordinates are inside the image x, y = self.wcs.wcs_world2pix(self.lon, self.lat, 0) print('x y ', x, y) if x >= 0 and x <= self.data.nx and y >= 0 and y <= self.data.ny: print('Source inside the FITS cube') else: self.data = None self.wcs = None print('The selected FITS is not a valid file') except: self.data = None self.wcs = None print('The selected FITS is not a valid file')
def exportContours(self): """Export defined contours.""" itab = self.itabs.currentIndex() ic0 = self.ici[itab] ih0 = self.ihi[itab] if ic0.contour is not None: if ic0.title in ['Flux', 'Coverage map', 'Flux [no atm. corr.]']: source = self.specCube.instrument else: source = ic0.title info = [('source', source), ('levels', ih0.levels)] data = OrderedDict(info) # Open a dialog fd = QFileDialog() fd.setLabelText(QFileDialog.Accept, "Export as") fd.setNameFilters(["Json Files (*.json)", "All Files (*)"]) fd.setOptions(QFileDialog.DontUseNativeDialog) fd.setViewMode(QFileDialog.List) if (fd.exec()): filenames = fd.selectedFiles() filename = filenames[0] if filename[-5:] != '.json': filename += '.json' print("Exporting contour levels to file: ", filename) with io.open(filename, mode='w') as f: str_ = json.dumps(data, indent=2, separators=(',', ': '), ensure_ascii=False, cls=MyEncoder) f.write(str_) self.sb.showMessage("Aperture exported in file " + filename, 3000) else: return
def get_open_dialog(directory_mode=False, parent=None, name_filter="full") -> QFileDialog: fip = FileIconProvider() dialog = QFileDialog(parent) dialog.setIconProvider(fip) dialog.setDirectory(RECENT_PATH) if directory_mode: dialog.setFileMode(QFileDialog.Directory) dialog.setWindowTitle("Open Folder") else: dialog.setFileMode(QFileDialog.ExistingFiles) dialog.setWindowTitle("Open Files") if name_filter == "full": name_filter = "All files (*);;Complex (*.complex);;" \ "Complex16 unsigned (*.complex16u);;" \ "Complex16 signed (*.complex16s);;" \ "Wave (*.wav);;" \ "Protocols (*.proto.xml *.proto);;" \ "Fuzzprofiles (*.fuzz.xml *.fuzz);;" \ "Plain bits (*.txt);;" \ "Tar Archives (*.tar *.tar.gz *.tar.bz2);;" \ "Zip Archives (*.zip)" elif name_filter == "proto": name_filter = "Protocols (*.proto.xml *.proto);;" elif name_filter == "fuzz": name_filter = "Fuzzprofiles (*.fuzz.xml *.fuzz);;" dialog.setNameFilter(name_filter) dialog.setOptions(QFileDialog.DontResolveSymlinks) dialog.setViewMode(QFileDialog.Detail) return dialog
def _fileDialog(acceptMode, fileMode, parent=None, caption='', directory='', filters=(), selectedFilter=None, options=0): nameFilters = make_filters(filters) dialog = QFileDialog(parent, caption, directory) dialog.setNameFilters(nameFilters) dialog.setAcceptMode(acceptMode) dialog.setFileMode(fileMode) dialog.setOptions(QFileDialog.Options(options)) if selectedFilter is not None: dialog.selectNameFilter(nameFilters[selectedFilter]) if dialog.exec_() != QDialog.Accepted: return None filename = dialog.selectedFiles()[0] if fileMode != QFileDialog.Directory: selectedFilter = nameFilters.index(dialog.selectedNameFilter()) _, ext = os.path.splitext(filename) if not ext: ext = filters[selectedFilter][1] # use first extension if ext.startswith('*.') and ext != '*.*': return filename + ext[1:] # remove leading '*' return filename
def file_dialog(dir='', for_open=True, fmt='', is_folder=False): """Dialog z eksploratorem Windows. Otwieranie/tworzenie folderów i plików.""" options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog options |= QFileDialog.DontUseCustomDirectoryIcons dialog = QFileDialog() dialog.setOptions(options) dialog.setFilter(dialog.filter() | QDir.Hidden) if is_folder: # Otwieranie folderu dialog.setFileMode(QFileDialog.DirectoryOnly) else: # Otwieranie pliku dialog.setFileMode(QFileDialog.AnyFile) # Otwieranie / zapisywanie: dialog.setAcceptMode( QFileDialog.AcceptOpen) if for_open else dialog.setAcceptMode( QFileDialog.AcceptSave) # Ustawienie filtrowania rozszerzeń plików: if fmt != '' and not is_folder: dialog.setDefaultSuffix(fmt) dialog.setNameFilters([f'{fmt} (*.{fmt})']) # Ścieżka startowa: if dir != '': dialog.setDirectory(str(dir)) else: dialog.setDirectory(str(os.environ["HOMEPATH"])) # Przekazanie ścieżki folderu/pliku: if dialog.exec_() == QDialog.Accepted: path = dialog.selectedFiles()[0] return path else: return ''
def show_files_request(qt_widget, title, root_path): opts = QFileDialog.DontUseNativeDialog dialog = QFileDialog() dialog.setWindowTitle(title) dialog.setViewMode(QFileDialog.List) dialog.setOptions(opts) filenames = dialog.getOpenFileNames(qt_widget, title, root_path) return filenames[0]
def saveDialog(name, filter): """ Create non-native save file dialog. """ qfd = QFileDialog(getWindow(), name) qfd.setNameFilter(filter) qfd.setFileMode(QFileDialog.AnyFile) qfd.setOptions(QFileDialog.DontUseNativeDialog) qfd.setAcceptMode(QFileDialog.AcceptSave) qfd.setViewMode(QFileDialog.List) return qfd
def openDialog(name, filter): """ Create non-native open file dialog. """ qfd = QFileDialog(getWindow(), name) qfd.setNameFilter(filter) qfd.setFileMode(QFileDialog.ExistingFile) qfd.setOptions(QFileDialog.DontUseNativeDialog) qfd.setAcceptMode(QFileDialog.AcceptOpen) qfd.setViewMode(QFileDialog.List) return qfd
def write_cfg(self): dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.write_cfg_settings(settings)
def action_select_output_files_path(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog options |= QFileDialog.DontUseCustomDirectoryIcons dialog = QFileDialog() dialog.setOptions(options) dialog.setFilter(dialog.filter() | QDir.Hidden) path = dialog.getExistingDirectory(self, 'Select directory', options=options) if path: self.lineedit_output_files_path.setText(path)
def set_edii_path(config): dlg = QFileDialog(None, 'Set path to EDII service', config.get_value('edii_path')) dlg.setAcceptMode(QFileDialog.AcceptOpen) dlg.setOptions(QFileDialog.ShowDirsOnly | QFileDialog.ReadOnly) ret = dlg.exec_() if ret != QDialog.Accepted: return config.set_value('edii_path', dlg.selectedFiles()[0])
def GetIconPath(self): from PyQt5.QtWidgets import QFileDialog, QDialog opt = QtWidgets.QFileDialog.Options() opt |= QtWidgets.QFileDialog.DontUseSheet dialog = QFileDialog() dialog.setOptions(opt) dialog.setDirectory(self.appPath) path = QtWidgets.QFileDialog.getExistingDirectory( None, "Default Icon Directory...", self.appPath, options=opt) if path: self.IconPath.setText(path)
def create_file_dialog(): """ Create a file dialog object, ready to use :return: """ dialog = QFileDialog() dialog.setFileMode(QFileDialog.DirectoryOnly) options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog options |= QFileDialog.ShowDirsOnly dialog.setOptions(options) return dialog
def _open(self): proxy_model = ExecutableFilterModel() options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog dialog = QFileDialog(self.widget, "Select a source port", self.config.get("sourcePortDir")) dialog.setOptions(options) dialog.setProxyModel(proxy_model) if dialog.exec_() == QDialog.Accepted: filename = dialog.selectedUrls()[0].toLocalFile() self.saveSourcePortPath(filename) self.setSourcePort(filename)
def _openProject(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.DirectoryOnly) dialog.setOptions(QFileDialog.ShowDirsOnly) if dialog.exec(): # TODO: this returns a list... should give user an error if they select multiple dir = dialog.selectedFiles()[0] self._tree = builder.build(root=dir) for doc in self._tree: self._docTree.addItem(doc) self._reqStack.addDoc(doc) self._reqView.addDoc(doc) self.mainContainer.show()
def selectFile(self, label): fd = QFileDialog() fd.setWindowTitle('Open ' + label + ' File') fd.setLabelText(QFileDialog.Accept, "Select " + label) fd.setNameFilters(["Fits Files (*.fit* *.FIT*)"]) fd.setOptions(QFileDialog.DontUseNativeDialog) fd.setViewMode(QFileDialog.List) if (fd.exec()): fileNames = fd.selectedFiles() return fileNames[0] else: return None print("No file selected")
def write_s2p(self, gain): dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p') dialog.setDefaultSuffix('s2p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') freq = self.dut.freq gamma = self.gamma(freq) fh.write('# GHz S MA R 50\n') for i in range(freq.size): fh.write('0.0%.8d %8.6f %7.2f %8.6f %7.2f 0.000000 0.00 0.000000 0.00\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True))) fh.close()
def write_s1p(self): dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p') dialog.setDefaultSuffix('s1p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gamma = self.gamma() size = self.sizeValue.value() fh.write('# GHz S MA R 50\n') for i in range(0, size): fh.write('0.0%.8d %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True))) fh.close()
def write_csv(self): dialog = QFileDialog(self, 'Write csv file', '.', '*.csv') dialog.setDefaultSuffix('csv') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gamma = self.gamma() size = self.sizeValue.value() fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n') for i in range(0, size): fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (self.xaxis[i], self.open.real[i], self.open.imag[i], self.short.real[i], self.short.imag[i], self.load.real[i], self.load.imag[i], self.dut.real[i], self.dut.imag[i])) fh.close()
def write_csv(self): dialog = QFileDialog(self, 'Write csv file', '.', '*.csv') dialog.setDefaultSuffix('csv') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') f = self.dut.freq o = self.interp(f, self.open) s = self.interp(f, self.short) l = self.interp(f, self.load) d = self.dut.data fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n') for i in range(f.size): fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i])) fh.close()
def _get_save_file_name(self, file_format): if file_format == export.FileFormat.XLSX: file_filter = FileNameFilters.xlsx_file extension = 'xlsx' else: file_filter = FileNameFilters.csv_file extension = 'csv' save_dialog = QFileDialog(parent=self, caption=_('Save listing as...'), filter=file_filter) save_dialog.setOptions(QFileDialog.DontUseNativeDialog) save_dialog.setDefaultSuffix(extension) save_dialog.setFileMode(QFileDialog.AnyFile) save_dialog.setAcceptMode(QFileDialog.AcceptSave) filename = None if save_dialog.exec_(): filename_list = save_dialog.selectedFiles() if len(filename_list) == 1: filename = filename_list[0] return filename
def dialog_export_exam_config(self): """Displays the dialog for exporting the current exam configuration. If accepted by the user, it returns the filename. Returns None if cancelled. """ save_dialog = QFileDialog(parent=self.window, caption=_('Save exam configration as...'), filter=_('Exam configuration (*.eye)')) save_dialog.setOptions(QFileDialog.DontUseNativeDialog) save_dialog.setDefaultSuffix('eye') save_dialog.setFileMode(QFileDialog.AnyFile) save_dialog.setAcceptMode(QFileDialog.AcceptSave) filename = None if save_dialog.exec_(): filename_list = save_dialog.selectedFiles() if len(filename_list) == 1: filename = filename_list[0] return filename
def get_open_dialog(directory_mode=False, parent=None, name_filter="full") -> QFileDialog: fip = FileIconProvider() dialog = QFileDialog(parent=parent, directory=RECENT_PATH) dialog.setIconProvider(fip) if directory_mode: dialog.setFileMode(QFileDialog.Directory) dialog.setWindowTitle("Open Folder") else: dialog.setFileMode(QFileDialog.ExistingFiles) dialog.setWindowTitle("Open Files") if name_filter == "full": name_filter = "All Files (*);;" \ "Complex (*.complex);;" \ "Complex16 unsigned (*.complex16u *.cu8);;" \ "Complex16 signed (*.complex16s *.cs8);;" \ "WAV (*.wav);;" \ "Protocols (*.proto.xml *.proto);;" \ "Binary Protocols (*.bin);;" \ "Fuzzing Profiles (*.fuzz.xml *.fuzz);;" \ "Simulator (*.sim.xml *.sim)" \ "Plain Bits (*.txt);;" \ "Tar Archives (*.tar *.tar.gz *.tar.bz2);;" \ "Zip Archives (*.zip)" elif name_filter == "proto": name_filter = "Protocols (*.proto.xml *.proto);; Binary Protocols (*.bin)" elif name_filter == "fuzz": name_filter = "Fuzzprofiles (*.fuzz.xml *.fuzz)" elif name_filter == "simulator": name_filter = "Simulator (*.sim.xml *.sim)" dialog.setNameFilter(name_filter) dialog.setOptions(QFileDialog.DontResolveSymlinks) dialog.setViewMode(QFileDialog.Detail) return dialog
def browse(self): """ Open a file dialog and select a user specified file. """ formats = [ "Text - comma separated (*.csv, *)", "Text - tab separated (*.tsv, *)", "Text - all files (*)" ] dlg = QFileDialog( self, windowTitle="Open Data File", acceptMode=QFileDialog.AcceptOpen, fileMode=QFileDialog.ExistingFile ) dlg.setNameFilters(formats) state = self.dialog_state lastdir = state.get("directory", "") lastfilter = state.get("filter", "") if lastdir and os.path.isdir(lastdir): dlg.setDirectory(lastdir) if lastfilter: dlg.selectNameFilter(lastfilter) status = dlg.exec_() dlg.deleteLater() if status == QFileDialog.Accepted: self.dialog_state["directory"] = dlg.directory().absolutePath() self.dialog_state["filter"] = dlg.selectedNameFilter() selected_filter = dlg.selectedNameFilter() path = dlg.selectedFiles()[0] # pre-flight check; try to determine the nature of the file mtype = _mime_type_for_path(path) if not mtype.inherits("text/plain"): mb = QMessageBox( parent=self, windowTitle="", icon=QMessageBox.Question, text="The '{basename}' may be a binary file.\n" "Are you sure you want to continue?".format( basename=os.path.basename(path)), standardButtons=QMessageBox.Cancel | QMessageBox.Yes ) mb.setWindowModality(Qt.WindowModal) if mb.exec() == QMessageBox.Cancel: return # initialize dialect based on selected extension if selected_filter in formats[:-1]: filter_idx = formats.index(selected_filter) if filter_idx == 0: dialect = csv.excel() elif filter_idx == 1: dialect = csv.excel_tab() else: dialect = csv.excel_tab() header = True else: try: dialect, header = sniff_csv_with_path(path) except Exception: dialect, header = csv.excel(), True options = None # Search for path in history. # If found use the stored params to initialize the import dialog items = self.itemsFromSettings() idx = index_where(items, lambda t: samepath(t[0], path)) if idx is not None: _, options_ = items[idx] if options_ is not None: options = options_ if options is None: if not header: rowspec = [] else: rowspec = [(range(0, 1), RowSpec.Header)] options = Options( encoding="utf-8", dialect=dialect, rowspec=rowspec) dlg = CSVImportDialog( self, windowTitle="Import Options", sizeGripEnabled=True) dlg.setWindowModality(Qt.WindowModal) dlg.setPath(path) dlg.setOptions(options) status = dlg.exec_() dlg.deleteLater() if status == QDialog.Accepted: self.set_selected_file(path, dlg.options())
class MainController(QMainWindow): def __init__(self, *args): super().__init__(*args) self.ui = Ui_MainWindow() self.ui.setupUi(self) OptionsController.write_default_options() self.project_save_timer = QTimer() self.project_manager = ProjectManager(self) self.plugin_manager = PluginManager() self.signal_tab_controller = SignalTabController(self.project_manager, parent=self.ui.tab_interpretation) self.ui.tab_interpretation.layout().addWidget(self.signal_tab_controller) self.compare_frame_controller = CompareFrameController(parent=self.ui.tab_protocol, plugin_manager=self.plugin_manager, project_manager=self.project_manager) self.compare_frame_controller.ui.splitter.setSizes([1, 1000000]) self.ui.tab_protocol.layout().addWidget(self.compare_frame_controller) self.generator_tab_controller = GeneratorTabController(self.compare_frame_controller, self.project_manager, parent=self.ui.tab_generator) self.undo_group = QUndoGroup() self.undo_group.addStack(self.signal_tab_controller.signal_undo_stack) self.undo_group.addStack(self.compare_frame_controller.protocol_undo_stack) self.undo_group.addStack(self.generator_tab_controller.generator_undo_stack) self.undo_group.setActiveStack(self.signal_tab_controller.signal_undo_stack) self.participant_legend_model = ParticipantLegendListModel(self.project_manager.participants) self.ui.listViewParticipants.setModel(self.participant_legend_model) gtc = self.generator_tab_controller gtc.ui.splitter.setSizes([gtc.width() / 0.7, gtc.width() / 0.3]) self.ui.tab_generator.layout().addWidget(self.generator_tab_controller) self.signal_protocol_dict = {} # type: dict[SignalFrameController, ProtocolAnalyzer] self.ui.lnEdtTreeFilter.setClearButtonEnabled(True) group = QActionGroup(self) self.ui.actionFSK.setActionGroup(group) self.ui.actionOOK.setActionGroup(group) self.ui.actionNone.setActionGroup(group) self.ui.actionPSK.setActionGroup(group) self.recentFileActionList = [] self.create_connects() self.init_recent_file_action_list(constants.SETTINGS.value("recentFiles", [])) self.filemodel = FileSystemModel(self) path = QDir.homePath() self.filemodel.setIconProvider(FileIconProvider()) self.filemodel.setRootPath(path) self.file_proxy_model = FileFilterProxyModel(self) self.file_proxy_model.setSourceModel(self.filemodel) self.ui.fileTree.setModel(self.file_proxy_model) self.ui.fileTree.setRootIndex(self.file_proxy_model.mapFromSource(self.filemodel.index(path))) self.ui.fileTree.setToolTip(path) self.ui.fileTree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self.ui.fileTree.header().setSectionResizeMode(1, QHeaderView.Stretch) self.ui.fileTree.setFocus() self.generator_tab_controller.table_model.cfc = self.compare_frame_controller self.ui.actionConvert_Folder_to_Project.setEnabled(False) undo_action = self.undo_group.createUndoAction(self) undo_action.setIcon(QIcon.fromTheme("edit-undo")) undo_action.setShortcut(QKeySequence.Undo) self.ui.menuEdit.insertAction(self.ui.actionDecoding, undo_action) redo_action = self.undo_group.createRedoAction(self) redo_action.setIcon(QIcon.fromTheme("edit-redo")) redo_action.setShortcut(QKeySequence.Redo) self.ui.menuEdit.insertAction(self.ui.actionDecoding, redo_action) self.ui.menuEdit.insertSeparator(self.ui.actionDecoding) self.ui.actionAbout_Qt.setIcon(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png")) self.ui.splitter.setSizes([0, 1]) self.refresh_main_menu() self.apply_default_view(constants.SETTINGS.value('default_view', type=int)) self.project_save_timer.start(ProjectManager.AUTOSAVE_INTERVAL_MINUTES * 60 * 1000) self.ui.actionProject_settings.setVisible(False) self.ui.actionSave_project.setVisible(False) def create_connects(self): self.ui.actionFullscreen_mode.setShortcut(QKeySequence.FullScreen) self.ui.actionOpen.setShortcut(QKeySequence(QKeySequence.Open)) self.ui.actionOpen_directory.setShortcut(QKeySequence("Ctrl+Shift+O")) self.ui.menuEdit.aboutToShow.connect(self.on_edit_menu_about_to_show) self.ui.actionNew_Project.triggered.connect(self.on_new_project_action_triggered) self.ui.actionNew_Project.setShortcut(QKeySequence.New) self.ui.actionProject_settings.triggered.connect(self.on_project_settings_action_triggered) self.ui.actionSave_project.triggered.connect(self.project_manager.saveProject) self.ui.actionAbout_AutomaticHacker.triggered.connect(self.on_show_about_clicked) self.ui.actionRecord.triggered.connect(self.on_show_record_dialog_action_triggered) self.ui.actionFullscreen_mode.triggered.connect(self.on_fullscreen_action_triggered) self.ui.actionSaveAllSignals.triggered.connect(self.signal_tab_controller.save_all) self.ui.actionClose_all.triggered.connect(self.on_close_all_action_triggered) self.ui.actionOpen.triggered.connect(self.on_open_file_action_triggered) self.ui.actionOpen_directory.triggered.connect(self.on_open_directory_action_triggered) self.ui.actionDecoding.triggered.connect(self.on_show_decoding_dialog_triggered) self.ui.actionSpectrum_Analyzer.triggered.connect(self.on_show_spectrum_dialog_action_triggered) self.ui.actionOptions.triggered.connect(self.show_options_dialog_action_triggered) self.ui.actionSniff_protocol.triggered.connect(self.show_proto_sniff_dialog) self.ui.actionAbout_Qt.triggered.connect(QApplication.instance().aboutQt) self.ui.btnFileTreeGoUp.clicked.connect(self.on_btn_file_tree_go_up_clicked) self.ui.fileTree.directory_open_wanted.connect(self.project_manager.set_project_folder) self.signal_tab_controller.frame_closed.connect(self.close_signal_frame) self.signal_tab_controller.signal_created.connect(self.add_signal) self.signal_tab_controller.ui.scrollArea.files_dropped.connect(self.on_files_dropped) self.signal_tab_controller.files_dropped.connect(self.on_files_dropped) self.signal_tab_controller.frame_was_dropped.connect(self.set_frame_numbers) self.compare_frame_controller.show_interpretation_clicked.connect( self.show_protocol_selection_in_interpretation) self.compare_frame_controller.files_dropped.connect(self.on_files_dropped) self.compare_frame_controller.show_decoding_clicked.connect(self.on_show_decoding_dialog_triggered) self.compare_frame_controller.ui.treeViewProtocols.files_dropped_on_group.connect( self.on_files_dropped_on_group) self.compare_frame_controller.participant_changed.connect(self.signal_tab_controller.on_participant_changed) self.compare_frame_controller.ui.treeViewProtocols.close_wanted.connect(self.on_cfc_close_wanted) self.compare_frame_controller.show_config_field_types_triggered.connect( self.on_show_field_types_config_action_triggered) self.ui.lnEdtTreeFilter.textChanged.connect(self.on_file_tree_filter_text_changed) self.ui.tabWidget.currentChanged.connect(self.on_selected_tab_changed) self.project_save_timer.timeout.connect(self.project_manager.saveProject) self.ui.actionConvert_Folder_to_Project.triggered.connect(self.project_manager.convert_folder_to_project) self.project_manager.project_loaded_status_changed.connect(self.ui.actionProject_settings.setVisible) self.project_manager.project_loaded_status_changed.connect(self.ui.actionSave_project.setVisible) self.project_manager.project_loaded_status_changed.connect(self.ui.actionConvert_Folder_to_Project.setDisabled) self.project_manager.project_updated.connect(self.on_project_updated) self.ui.textEditProjectDescription.textChanged.connect(self.on_text_edit_project_description_text_changed) self.ui.tabWidget_Project.tabBarDoubleClicked.connect(self.on_project_tab_bar_double_clicked) self.ui.listViewParticipants.doubleClicked.connect(self.on_project_settings_action_triggered) self.ui.actionShowFileTree.triggered.connect(self.on_action_show_filetree_triggered) self.ui.actionShowFileTree.setShortcut(QKeySequence("F10")) self.ui.menuFile.addSeparator() for i in range(constants.MAX_RECENT_FILE_NR): recent_file_action = QAction(self) recent_file_action.setVisible(False) recent_file_action.triggered.connect(self.on_open_recent_action_triggered) self.recentFileActionList.append(recent_file_action) self.ui.menuFile.addAction(self.recentFileActionList[i]) def add_plain_bits_from_txt(self, filename: str): protocol = ProtocolAnalyzer(None) protocol.filename = filename with open(filename) as f: for line in f: protocol.messages.append(Message.from_plain_bits_str(line.strip())) self.compare_frame_controller.add_protocol(protocol) self.compare_frame_controller.refresh() self.__add_empty_frame_for_filename(protocol, filename) def __add_empty_frame_for_filename(self, protocol: ProtocolAnalyzer, filename: str): sf = self.signal_tab_controller.add_empty_frame(filename, protocol) self.signal_protocol_dict[sf] = protocol self.set_frame_numbers() self.file_proxy_model.open_files.add(filename) def add_protocol_file(self, filename): proto = self.compare_frame_controller.add_protocol_from_file(filename) if proto: self.__add_empty_frame_for_filename(proto, filename) def add_fuzz_profile(self, filename): self.ui.tabWidget.setCurrentIndex(2) self.generator_tab_controller.load_from_file(filename) def add_signalfile(self, filename: str, group_id=0): if not os.path.exists(filename): QMessageBox.critical(self, self.tr("File not Found"), self.tr("The file {0} could not be found. Was it moved or renamed?").format( filename)) return already_qad_demodulated = False if filename.endswith(".wav"): cb = QCheckBox("Signal in file is already quadrature demodulated") msg = self.tr("You selected a .wav file as signal.\n" "Universal Radio Hacker (URH) will interpret it as real part of the signal.\n" "Protocol results may be bad due to missing imaginary part.\n\n" "Load a complex file if you experience problems.\n" "You have been warned.") msg_box = QMessageBox(QMessageBox.Information, "WAV file selected", msg) msg_box.addButton(QMessageBox.Ok) msg_box.addButton(QMessageBox.Abort) msg_box.setCheckBox(cb) reply = msg_box.exec() if reply != QMessageBox.Ok: return already_qad_demodulated = cb.isChecked() sig_name = os.path.splitext(os.path.basename(filename))[0] # Use default sample rate for signal # Sample rate will be overriden in case of a project later signal = Signal(filename, sig_name, wav_is_qad_demod=already_qad_demodulated, sample_rate=self.project_manager.device_conf["sample_rate"]) if self.project_manager.project_file is None: self.adjust_for_current_file(signal.filename) self.file_proxy_model.open_files.add(filename) self.add_signal(signal, group_id) def add_signal(self, signal, group_id=0): self.setCursor(Qt.WaitCursor) pa = ProtocolAnalyzer(signal) sig_frame = self.signal_tab_controller.add_signal_frame(pa) pa = self.compare_frame_controller.add_protocol(pa, group_id) signal.blockSignals(True) has_entry = self.project_manager.read_project_file_for_signal(signal) if not has_entry: signal.auto_detect() signal.blockSignals(False) self.signal_protocol_dict[sig_frame] = pa sig_frame.refresh(draw_full_signal=True) # Hier wird das Protokoll ausgelesen if self.project_manager.read_participants_for_signal(signal, pa.messages): sig_frame.ui.gvSignal.redraw_view() sig_frame.ui.gvSignal.auto_fit_view() self.set_frame_numbers() self.compare_frame_controller.filter_search_results() self.refresh_main_menu() self.unsetCursor() def close_protocol(self, protocol): self.compare_frame_controller.remove_protocol(protocol) # Needs to be removed in generator also, otherwise program crashes, # if item from tree in generator is selected and corresponding signal is closed self.generator_tab_controller.tree_model.remove_protocol(protocol) protocol.eliminate() def close_signal_frame(self, signal_frame: SignalFrameController): try: self.project_manager.write_signal_information_to_project_file(signal_frame.signal) try: proto = self.signal_protocol_dict[signal_frame] except KeyError: proto = None if proto is not None: self.close_protocol(proto) del self.signal_protocol_dict[signal_frame] if self.signal_tab_controller.ui.scrlAreaSignals.minimumHeight() > signal_frame.height(): self.signal_tab_controller.ui.scrlAreaSignals.setMinimumHeight( self.signal_tab_controller.ui.scrlAreaSignals.minimumHeight() - signal_frame.height()) if signal_frame.signal is not None: # Non-Empty Frame (when a signal and not a protocol is opened) self.file_proxy_model.open_files.discard(signal_frame.signal.filename) signal_frame.eliminate() self.compare_frame_controller.ui.treeViewProtocols.expandAll() self.set_frame_numbers() self.refresh_main_menu() except Exception as e: Errors.generic_error(self.tr("Failed to close"), str(e), traceback.format_exc()) self.unsetCursor() def add_files(self, filepaths, group_id=0): num_files = len(filepaths) if num_files == 0: return for i, file in enumerate(filepaths): if not os.path.exists(file): continue if os.path.isdir(file): for f in self.signal_tab_controller.signal_frames: self.close_signal_frame(f) FileOperator.RECENT_PATH = file self.project_manager.set_project_folder(file) return _, file_extension = os.path.splitext(file) FileOperator.RECENT_PATH = os.path.split(file)[0] if file_extension == ".complex": self.add_signalfile(file, group_id) elif file_extension == ".coco": self.add_signalfile(file, group_id) elif file_extension == ".proto": self.add_protocol_file(file) elif file_extension == ".wav": self.add_signalfile(file, group_id) elif file_extension == ".fuzz": self.add_fuzz_profile(file) elif file_extension == ".txt": self.add_plain_bits_from_txt(file) else: self.add_signalfile(file, group_id) def set_frame_numbers(self): self.signal_tab_controller.set_frame_numbers() def closeEvent(self, event: QCloseEvent): self.project_manager.saveProject() super().closeEvent(event) def close_all(self): self.filemodel.setRootPath(QDir.homePath()) self.ui.fileTree.setRootIndex(self.file_proxy_model.mapFromSource(self.filemodel.index(QDir.homePath()))) self.project_manager.saveProject() self.signal_tab_controller.close_all() self.compare_frame_controller.reset() self.generator_tab_controller.table_model.protocol.clear() self.generator_tab_controller.refresh_tree() self.generator_tab_controller.refresh_table() self.generator_tab_controller.refresh_label_list() self.project_manager.project_path = "" self.project_manager.project_file = None self.signal_tab_controller.signal_undo_stack.clear() self.compare_frame_controller.protocol_undo_stack.clear() self.generator_tab_controller.generator_undo_stack.clear() def show_options_dialog_specific_tab(self, tab_index: int): op = OptionsController(self.plugin_manager.installed_plugins, parent=self) op.values_changed.connect(self.on_options_changed) op.ui.tabWidget.setCurrentIndex(tab_index) op.show() def refresh_main_menu(self): enable = len(self.signal_protocol_dict) > 0 self.ui.actionSaveAllSignals.setEnabled(enable) self.ui.actionClose_all.setEnabled(enable) def apply_default_view(self, view_index: int): self.compare_frame_controller.ui.cbProtoView.setCurrentIndex(view_index) self.generator_tab_controller.ui.cbViewType.setCurrentIndex(view_index) for sig_frame in self.signal_tab_controller.signal_frames: sig_frame.ui.cbProtoView.setCurrentIndex(view_index) def show_project_settings(self): pdc = ProjectDialogController(new_project=False, project_manager=self.project_manager, parent=self) pdc.finished.connect(self.on_project_dialog_finished) pdc.show() def collapse_project_tab_bar(self): self.ui.tabParticipants.hide() self.ui.tabDescription.hide() self.ui.tabWidget_Project.setMaximumHeight(self.ui.tabWidget_Project.tabBar().height()) def expand_project_tab_bar(self): self.ui.tabDescription.show() self.ui.tabParticipants.show() self.ui.tabWidget_Project.setMaximumHeight(9000) @pyqtSlot() def on_project_tab_bar_double_clicked(self): if self.ui.tabParticipants.isVisible(): self.collapse_project_tab_bar() else: self.expand_project_tab_bar() @pyqtSlot() def on_project_updated(self): self.participant_legend_model.participants = self.project_manager.participants self.participant_legend_model.update() self.compare_frame_controller.refresh() self.ui.textEditProjectDescription.setText(self.project_manager.description) @pyqtSlot() def on_fullscreen_action_triggered(self): if self.ui.actionFullscreen_mode.isChecked(): self.showFullScreen() else: self.showMaximized() @pyqtSlot(str) def adjust_for_current_file(self, file_path): if file_path is None: return if file_path in FileOperator.archives.keys(): file_path = copy.copy(FileOperator.archives[file_path]) settings = constants.SETTINGS recent_file_paths = settings.value("recentFiles", []) recent_file_paths = [] if recent_file_paths is None else recent_file_paths # check None for OSX recent_file_paths = [p for p in recent_file_paths if p != file_path and p is not None and os.path.exists(p)] recent_file_paths.insert(0, file_path) recent_file_paths = recent_file_paths[:constants.MAX_RECENT_FILE_NR] self.init_recent_file_action_list(recent_file_paths) settings.setValue("recentFiles", recent_file_paths) def init_recent_file_action_list(self, recent_file_paths: list): for i in range(len(self.recentFileActionList)): self.recentFileActionList[i].setVisible(False) if recent_file_paths is None: return for i, file_path in enumerate(recent_file_paths): if os.path.isfile(file_path): display_text = os.path.basename(file_path) self.recentFileActionList[i].setIcon(QIcon()) elif os.path.isdir(file_path): head, tail = os.path.split(file_path) display_text = tail head, tail = os.path.split(head) if tail: display_text = tail + "/" + display_text self.recentFileActionList[i].setIcon(QIcon.fromTheme("folder")) else: continue self.recentFileActionList[i].setText(display_text) self.recentFileActionList[i].setData(file_path) self.recentFileActionList[i].setVisible(True) @pyqtSlot() def on_show_field_types_config_action_triggered(self): self.show_options_dialog_specific_tab(tab_index=2) @pyqtSlot() def on_open_recent_action_triggered(self): action = self.sender() try: if os.path.isdir(action.data()): self.project_manager.set_project_folder(action.data()) elif os.path.isfile(action.data()): self.setCursor(Qt.WaitCursor) self.add_files(FileOperator.uncompress_archives([action.data()], QDir.tempPath())) self.unsetCursor() except Exception as e: Errors.generic_error(self.tr("Failed to open"), str(e), traceback.format_exc()) self.unsetCursor() @pyqtSlot() def on_show_about_clicked(self): descr = "<b><h2>Universal Radio Hacker</h2></b>Version: {0}<br />" \ "GitHub: <a href='https://github.com/jopohl/urh'>https://github.com/jopohl/urh</a><br /><br />" \ "Creators:<i><ul><li>" \ "Johannes Pohl <<a href='mailto:[email protected]'>[email protected]</a>></li>" \ "<li>Andreas Noack <<a href='mailto:[email protected]'>[email protected]</a>></li>" \ "</ul></i>".format(version.VERSION) QMessageBox.about(self, self.tr("About"), self.tr(descr)) @pyqtSlot(int, int, int, int) def show_protocol_selection_in_interpretation(self, start_message, start, end_message, end): cfc = self.compare_frame_controller msg_total = 0 last_sig_frame = None for protocol in cfc.protocol_list: if not protocol.show: continue n = protocol.num_messages view_type = cfc.ui.cbProtoView.currentIndex() messages = [i - msg_total for i in range(msg_total, msg_total + n) if start_message <= i <= end_message] if len(messages) > 0: try: signal_frame = next((sf for sf, pf in self.signal_protocol_dict.items() if pf == protocol)) except StopIteration: QMessageBox.critical(self, self.tr("Error"), self.tr("Could not find corresponding signal frame.")) return signal_frame.set_roi_from_protocol_analysis(min(messages), start, max(messages), end + 1, view_type) last_sig_frame = signal_frame msg_total += n focus_frame = last_sig_frame if last_sig_frame is not None: self.signal_tab_controller.ui.scrollArea.ensureWidgetVisible(last_sig_frame, 0, 0) QApplication.instance().processEvents() self.ui.tabWidget.setCurrentIndex(0) if focus_frame is not None: focus_frame.ui.txtEdProto.setFocus() @pyqtSlot(str) def on_file_tree_filter_text_changed(self, text: str): if len(text) > 0: self.filemodel.setNameFilters(["*" + text + "*"]) else: self.filemodel.setNameFilters(["*"]) @pyqtSlot() def on_show_decoding_dialog_triggered(self): signals = [sf.signal for sf in self.signal_tab_controller.signal_frames] decoding_controller = DecoderWidgetController( self.compare_frame_controller.decodings, signals, self.project_manager, parent=self) decoding_controller.finished.connect(self.update_decodings) decoding_controller.show() decoding_controller.decoder_update() @pyqtSlot() def update_decodings(self): self.compare_frame_controller.load_decodings() self.compare_frame_controller.fill_decoding_combobox() self.compare_frame_controller.refresh_existing_encodings() self.generator_tab_controller.refresh_existing_encodings(self.compare_frame_controller.decodings) @pyqtSlot(int) def on_selected_tab_changed(self, index: int): if index == 0: self.undo_group.setActiveStack(self.signal_tab_controller.signal_undo_stack) elif index == 1: self.undo_group.setActiveStack(self.compare_frame_controller.protocol_undo_stack) self.compare_frame_controller.ui.tblViewProtocol.resize_columns() self.compare_frame_controller.ui.tblViewProtocol.resize_vertical_header() h = max(self.compare_frame_controller.ui.btnSaveProto.height(), self.generator_tab_controller.ui.btnSave.height()) self.compare_frame_controller.ui.btnSaveProto.setMinimumHeight(h) th = self.compare_frame_controller.ui.tabWidget.tabBar().height() for i in range(self.compare_frame_controller.ui.tabWidget.count()): self.compare_frame_controller.ui.tabWidget.widget(i).layout().setContentsMargins(0, 7 + h - th, 0, 0) elif index == 2: self.undo_group.setActiveStack(self.generator_tab_controller.generator_undo_stack) h = max(self.compare_frame_controller.ui.btnSaveProto.height(), self.generator_tab_controller.ui.btnSave.height()) self.generator_tab_controller.ui.btnSave.setMinimumHeight(h) th = self.generator_tab_controller.ui.tabWidget.tabBar().height() for i in range(self.generator_tab_controller.ui.tabWidget.count()): self.generator_tab_controller.ui.tabWidget.widget(i).layout().setContentsMargins(0, 7 + h - th, 0, 0) @pyqtSlot() def on_show_record_dialog_action_triggered(self): pm = self.project_manager try: r = ReceiveDialogController(pm, parent=self) except OSError as e: logger.error(repr(e)) return if r.has_empty_device_list: Errors.no_device() r.close() return r.recording_parameters.connect(pm.set_recording_parameters) r.files_recorded.connect(self.on_signals_recorded) r.show() @pyqtSlot() def show_proto_sniff_dialog(self): pm = self.project_manager signal = next((proto.signal for proto in self.compare_frame_controller.protocol_list), None) bit_len = signal.bit_len if signal else 100 mod_type = signal.modulation_type if signal else 1 tolerance = signal.tolerance if signal else 5 noise = signal.noise_threshold if signal else 0.001 center = signal.qad_center if signal else 0.02 psd = ProtocolSniffDialogController(pm, noise, center, bit_len, tolerance, mod_type, self.compare_frame_controller.decodings, encoding_index=self.compare_frame_controller.ui.cbDecoding.currentIndex(), parent=self) if psd.has_empty_device_list: Errors.no_device() psd.close() else: psd.recording_parameters.connect(pm.set_recording_parameters) psd.protocol_accepted.connect(self.compare_frame_controller.add_sniffed_protocol_messages) psd.show() @pyqtSlot() def on_show_spectrum_dialog_action_triggered(self): pm = self.project_manager r = SpectrumDialogController(pm, parent=self) if r.has_empty_device_list: Errors.no_device() r.close() return r.recording_parameters.connect(pm.set_recording_parameters) r.show() @pyqtSlot(list) def on_signals_recorded(self, file_names: list): QApplication.instance().setOverrideCursor(Qt.WaitCursor) for filename in file_names: self.add_signalfile(filename) QApplication.instance().restoreOverrideCursor() @pyqtSlot() def show_options_dialog_action_triggered(self): self.show_options_dialog_specific_tab(tab_index=0) @pyqtSlot() def on_new_project_action_triggered(self): pdc = ProjectDialogController(parent=self) pdc.finished.connect(self.on_project_dialog_finished) pdc.show() @pyqtSlot() def on_project_settings_action_triggered(self): self.show_project_settings() @pyqtSlot() def on_edit_menu_about_to_show(self): self.ui.actionShowFileTree.setChecked(self.ui.splitter.sizes()[0] > 0) @pyqtSlot() def on_action_show_filetree_triggered(self): if self.ui.splitter.sizes()[0] > 0: self.ui.splitter.setSizes([0, 1]) else: self.ui.splitter.setSizes([1, 1]) @pyqtSlot() def on_project_dialog_finished(self): if self.sender().committed: if self.sender().new_project: for f in self.signal_tab_controller.signal_frames: self.close_signal_frame(f) self.project_manager.from_dialog(self.sender()) @pyqtSlot() def on_open_file_action_triggered(self): self.show_open_dialog(directory=False) @pyqtSlot() def on_open_directory_action_triggered(self): self.show_open_dialog(directory=True) def show_open_dialog(self, directory=False): fip = FileIconProvider() self.dialog = QFileDialog(self) self.dialog.setIconProvider(fip) self.dialog.setDirectory(FileOperator.RECENT_PATH) self.dialog.setWindowTitle("Open Folder") if directory: self.dialog.setFileMode(QFileDialog.Directory) else: self.dialog.setFileMode(QFileDialog.ExistingFiles) self.dialog.setNameFilter( "All files (*);;Complex (*.complex);;Complex16 unsigned (*.complex16u);;Complex16 signed (*.complex16s);;Wave (*.wav);;Protocols (*.proto);;" "Fuzzprofiles (*.fuzz);;Tar Archives (*.tar *.tar.gz *.tar.bz2);;Zip Archives (*.zip)") self.dialog.setOptions(QFileDialog.DontResolveSymlinks) self.dialog.setViewMode(QFileDialog.Detail) if self.dialog.exec_(): try: file_names = self.dialog.selectedFiles() folders = [folder for folder in file_names if os.path.isdir(folder)] if len(folders) > 0: folder = folders[0] for f in self.signal_tab_controller.signal_frames: self.close_signal_frame(f) self.project_manager.set_project_folder(folder) else: self.setCursor(Qt.WaitCursor) file_names = FileOperator.uncompress_archives(file_names, QDir.tempPath()) self.add_files(file_names) self.unsetCursor() except Exception as e: Errors.generic_error(self.tr("Failed to open"), str(e), traceback.format_exc()) QApplication.instance().restoreOverrideCursor() @pyqtSlot() def on_close_all_action_triggered(self): self.close_all() @pyqtSlot(list) def on_files_dropped(self, files): """ :type files: list of QtCore.QUrl """ self.__add_urls_to_group(files, group_id=0) @pyqtSlot(list, int) def on_files_dropped_on_group(self, files, group_id: int): """ :param group_id: :type files: list of QtCore.QUrl """ self.__add_urls_to_group(files, group_id=group_id) def __add_urls_to_group(self, file_urls, group_id=0): local_files = [file_url.toLocalFile() for file_url in file_urls if file_url.isLocalFile()] if len(local_files) > 0: self.setCursor(Qt.WaitCursor) self.add_files(FileOperator.uncompress_archives(local_files, QDir.tempPath()), group_id=group_id) self.unsetCursor() @pyqtSlot(list) def on_cfc_close_wanted(self, protocols: list): frame_protos = {sframe: protocol for sframe, protocol in self.signal_protocol_dict.items() if protocol in protocols} for frame in frame_protos: self.close_signal_frame(frame) for proto in (proto for proto in protocols if proto not in frame_protos.values()): # close protocols without associated signal frame self.close_protocol(proto) @pyqtSlot(dict) def on_options_changed(self, changed_options: dict): refresh_protocol_needed = "show_pause_as_time" in changed_options if refresh_protocol_needed: for sf in self.signal_tab_controller.signal_frames: sf.refresh_protocol() self.compare_frame_controller.refresh_field_types_for_labels() self.compare_frame_controller.set_shown_protocols() self.generator_tab_controller.set_network_sdr_send_button_visibility() self.generator_tab_controller.init_rfcat_plugin() if "default_view" in changed_options: self.apply_default_view(int(changed_options["default_view"])) @pyqtSlot() def on_text_edit_project_description_text_changed(self): self.project_manager.description = self.ui.textEditProjectDescription.toPlainText() @pyqtSlot() def on_btn_file_tree_go_up_clicked(self): cur_dir = self.filemodel.rootDirectory() if cur_dir.cdUp(): path = cur_dir.path() self.filemodel.setRootPath(path) self.ui.fileTree.setRootIndex(self.file_proxy_model.mapFromSource(self.filemodel.index(path)))