mirror of
https://github.com/jopohl/urh.git
synced 2026-03-18 06:06:48 +01:00
merge
This commit is contained in:
@@ -11,7 +11,7 @@ sudo python setup.py install
|
||||
```
|
||||
|
||||
# Running from source
|
||||
To run urh without installation, just run:
|
||||
To execute urh without installation, just run:
|
||||
```bash
|
||||
cd bin
|
||||
./urh
|
||||
|
||||
@@ -35,8 +35,9 @@ class FFTSceneManager(SceneManager):
|
||||
self.path_item.setPath(path)
|
||||
|
||||
try:
|
||||
peak_path = path_creator.create_path(np.log10(self.peak), start, end)
|
||||
self.peak_item.setPath(peak_path)
|
||||
if len(self.peak) > 0:
|
||||
peak_path = path_creator.create_path(np.log10(self.peak), start, end)
|
||||
self.peak_item.setPath(peak_path)
|
||||
except RuntimeWarning:
|
||||
pass
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ from PyQt5.QtWidgets import QMessageBox, QFrame, QAbstractItemView, QUndoStack,
|
||||
from urh import constants
|
||||
from urh.controller.OptionsController import OptionsController
|
||||
from urh.controller.ProtocolLabelController import ProtocolLabelController
|
||||
from urh.controller.ProtocolSniffDialogController import \
|
||||
ProtocolSniffDialogController
|
||||
from urh.controller.ProtocolSniffDialogController import ProtocolSniffDialogController
|
||||
from urh.models.LabelValueTableModel import LabelValueTableModel
|
||||
from urh.models.ProtocolLabelListModel import ProtocolLabelListModel
|
||||
from urh.models.ProtocolTableModel import ProtocolTableModel
|
||||
@@ -57,6 +56,7 @@ class CompareFrameController(QFrame):
|
||||
self.decimal_point = clocale.decimalPoint()
|
||||
|
||||
self.__active_group_ids = [0]
|
||||
self.selected_protocols = set()
|
||||
|
||||
self.protocol_model = ProtocolTableModel(self.proto_analyzer, self)
|
||||
""":type: ProtocolTableModel"""
|
||||
@@ -665,6 +665,7 @@ class CompareFrameController(QFrame):
|
||||
|
||||
active_group_ids = set()
|
||||
selection = QItemSelection()
|
||||
self.selected_protocols.clear()
|
||||
|
||||
for group, tree_items in self.proto_tree_model.protocol_tree_items.items():
|
||||
for i, tree_item in enumerate(tree_items):
|
||||
@@ -673,11 +674,9 @@ class CompareFrameController(QFrame):
|
||||
#index = self.proto_tree_model.createIndex(i, 0, tree_item)
|
||||
#selection.select(index, index)
|
||||
active_group_ids.add(group)
|
||||
self.selected_protocols.add(proto)
|
||||
|
||||
if active_group_ids == set(self.active_group_ids):
|
||||
ignore_table_model_on_update = True
|
||||
else:
|
||||
ignore_table_model_on_update = False
|
||||
if active_group_ids != set(self.active_group_ids):
|
||||
self.active_group_ids = list(active_group_ids)
|
||||
self.active_group_ids.sort()
|
||||
|
||||
@@ -698,7 +697,7 @@ class CompareFrameController(QFrame):
|
||||
self.ui.treeViewProtocols.selectionModel().select(selection, QItemSelectionModel.ClearAndSelect)
|
||||
self.ui.treeViewProtocols.blockSignals(False)
|
||||
|
||||
self.updateUI(ignore_table_model=ignore_table_model_on_update, resize_table=False)
|
||||
self.updateUI(ignore_table_model=True, resize_table=False)
|
||||
|
||||
@pyqtSlot(int)
|
||||
def handle_ref_index_changed(self, new_ref_index):
|
||||
|
||||
@@ -172,7 +172,7 @@ class GeneratorTabController(QWidget):
|
||||
prefix = "Amplitude"
|
||||
elif mod_type == "PSK":
|
||||
prefix = "Phase"
|
||||
elif mod_type == "FSK":
|
||||
elif mod_type in ("FSK", "GFSK"):
|
||||
prefix = "Frequency"
|
||||
else:
|
||||
prefix = "Unknown Modulation Type (This should not happen...)"
|
||||
|
||||
@@ -31,7 +31,6 @@ from urh.util.ProjectManager import ProjectManager
|
||||
|
||||
|
||||
class MainController(QMainWindow):
|
||||
resized = pyqtSignal()
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
@@ -343,7 +342,6 @@ class MainController(QMainWindow):
|
||||
|
||||
sframe.refresh(draw_full_signal=True) # Hier wird das Protokoll ausgelesen
|
||||
sframe.ui.gvSignal.autofit_view()
|
||||
self.resized.connect(sframe.redraw_after_resize)
|
||||
self.set_frame_numbers()
|
||||
self.ui.progressBar.setValue(99)
|
||||
QApplication.processEvents()
|
||||
@@ -383,10 +381,6 @@ class MainController(QMainWindow):
|
||||
self.set_frame_numbers()
|
||||
self.refresh_main_menu()
|
||||
|
||||
def resizeEvent(self, event: QResizeEvent):
|
||||
event.accept()
|
||||
self.resized.emit()
|
||||
|
||||
def updateRecentActionList(self):
|
||||
recentFilePaths = constants.SETTINGS.value("recentFiles")
|
||||
recentFilePaths = [p for p in recentFilePaths if os.path.exists(p)] if recentFilePaths else []
|
||||
@@ -435,7 +429,7 @@ class MainController(QMainWindow):
|
||||
|
||||
@pyqtSlot()
|
||||
def show_about(self):
|
||||
QMessageBox.about(self, self.tr("About"), self.tr("Version: {0}").format(version.VERSION))
|
||||
QMessageBox.about(self, self.tr("About"), self.tr("<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 />Contributors:<i><ul><li>Johannes Pohl <<a href='mailto:joahnnes.pohl90@gmail.com'>johannes.pohl90@gmail.com</a>></li><li>Andreas Noack <<a href='mailto:andreas.noack@fh-stralsund.de'>andreas.noack@fh-stralsund.de</a>></li></ul></i>").format(version.VERSION))
|
||||
|
||||
@pyqtSlot(CompareFrameController, int, int, int, int)
|
||||
def show_protocol_selection_in_interpretation(self, startblock, start, endblock, end):
|
||||
|
||||
@@ -27,13 +27,8 @@ class ModulatorDialogController(QDialog):
|
||||
|
||||
self.modulators = modulators
|
||||
|
||||
self.set_ui_for_current_modulator()
|
||||
|
||||
self.ui.doubleSpinBoxCarrierFreq.setValue(self.current_modulator.carrier_freq_hz)
|
||||
self.ui.doubleSpinBoxCarrierPhase.setValue(self.current_modulator.carrier_phase_deg)
|
||||
self.ui.spinBoxBitLength.setValue(self.current_modulator.samples_per_bit)
|
||||
self.ui.spinBoxSampleRate.setValue(self.current_modulator.sample_rate)
|
||||
self.ui.spinBoxParameter0.setValue(self.current_modulator.param_for_zero)
|
||||
self.ui.spinBoxParameter1.setValue(self.current_modulator.param_for_one)
|
||||
self.ui.cbShowDataBitsOnly.setText(self.tr("Show Only Data Sequence\n"))
|
||||
self.ui.cbShowDataBitsOnly.setEnabled(False)
|
||||
self.protocol = None
|
||||
@@ -45,7 +40,7 @@ class ModulatorDialogController(QDialog):
|
||||
|
||||
self.ui.chkBoxLockSIV.setDisabled(True)
|
||||
|
||||
self.ui.comboBoxModulationType.setCurrentIndex(self.current_modulator.modulation_type)
|
||||
|
||||
self.create_connects()
|
||||
self.on_modulation_type_changed()
|
||||
|
||||
@@ -58,14 +53,25 @@ class ModulatorDialogController(QDialog):
|
||||
mod = self.modulators[self.ui.comboBoxCustomModulations.currentIndex()]
|
||||
return mod
|
||||
|
||||
def set_ui_for_current_modulator(self):
|
||||
index = self.ui.comboBoxModulationType.findText("*("+self.current_modulator.modulation_type_str+")", Qt.MatchWildcard)
|
||||
self.ui.comboBoxModulationType.setCurrentIndex(index)
|
||||
self.ui.doubleSpinBoxCarrierFreq.setValue(self.current_modulator.carrier_freq_hz)
|
||||
self.ui.doubleSpinBoxCarrierPhase.setValue(self.current_modulator.carrier_phase_deg)
|
||||
self.ui.spinBoxBitLength.setValue(self.current_modulator.samples_per_bit)
|
||||
self.ui.spinBoxSampleRate.setValue(self.current_modulator.sample_rate)
|
||||
self.ui.spinBoxParameter0.setValue(self.current_modulator.param_for_zero)
|
||||
self.ui.spinBoxParameter1.setValue(self.current_modulator.param_for_one)
|
||||
|
||||
|
||||
def create_connects(self):
|
||||
self.ui.doubleSpinBoxCarrierFreq.valueChanged.connect(self.on_carrier_freq_changed)
|
||||
self.ui.doubleSpinBoxCarrierPhase.valueChanged.connect(self.on_carrier_phase_changed)
|
||||
self.ui.spinBoxBitLength.valueChanged.connect(self.on_bit_len_changed)
|
||||
self.ui.spinBoxSampleRate.valueChanged.connect(self.on_sample_rate_changed)
|
||||
self.ui.doubleSpinBoxCarrierFreq.editingFinished.connect(self.on_carrier_freq_changed)
|
||||
self.ui.doubleSpinBoxCarrierPhase.editingFinished.connect(self.on_carrier_phase_changed)
|
||||
self.ui.spinBoxBitLength.editingFinished.connect(self.on_bit_len_changed)
|
||||
self.ui.spinBoxSampleRate.editingFinished.connect(self.on_sample_rate_changed)
|
||||
self.ui.linEdDataBits.textChanged.connect(self.on_data_bits_changed)
|
||||
self.ui.spinBoxParameter0.valueChanged.connect(self.on_modulation_parameter_zero_changed)
|
||||
self.ui.spinBoxParameter1.valueChanged.connect(self.on_modulation_parameter_one_changed)
|
||||
self.ui.spinBoxParameter0.editingFinished.connect(self.on_modulation_parameter_zero_changed)
|
||||
self.ui.spinBoxParameter1.editingFinished.connect(self.on_modulation_parameter_one_changed)
|
||||
self.ui.comboBoxModulationType.currentIndexChanged.connect(self.on_modulation_type_changed)
|
||||
self.ui.gVOriginalSignal.zoomed.connect(self.on_orig_signal_zoomed)
|
||||
self.ui.cbShowDataBitsOnly.stateChanged.connect(self.on_show_data_bits_only_changed)
|
||||
@@ -80,6 +86,8 @@ class ModulatorDialogController(QDialog):
|
||||
self.ui.gVData.zoomed.connect(self.on_carrier_data_modulated_zoomed)
|
||||
self.ui.gVModulated.sel_area_width_changed.connect(self.on_modulated_selection_changed)
|
||||
self.ui.gVOriginalSignal.sel_area_width_changed.connect(self.on_original_selection_changed)
|
||||
self.ui.spinBoxGaussBT.editingFinished.connect(self.on_gauss_bt_edited)
|
||||
self.ui.spinBoxGaussFilterWidth.editingFinished.connect(self.on_gaus_filter_wdith_edited)
|
||||
|
||||
self.ui.chkBoxLockSIV.stateChanged.connect(self.on_lock_siv_changed)
|
||||
self.ui.btnRestoreBits.clicked.connect(self.on_btn_restore_bits_clicked)
|
||||
@@ -166,6 +174,11 @@ class ModulatorDialogController(QDialog):
|
||||
else:
|
||||
self.ui.btnRestoreBits.setEnabled(True)
|
||||
|
||||
def __cur_selected_mod_type(self):
|
||||
s = self.ui.comboBoxModulationType.currentText()
|
||||
return s[s.rindex("(")+1:s.rindex(")")]
|
||||
|
||||
|
||||
@pyqtSlot()
|
||||
def on_sample_rate_changed(self):
|
||||
if int(self.ui.spinBoxSampleRate.value()) > 0:
|
||||
@@ -183,15 +196,27 @@ class ModulatorDialogController(QDialog):
|
||||
self.current_modulator.param_for_one = self.ui.spinBoxParameter1.value()
|
||||
self.draw_modulated()
|
||||
|
||||
@pyqtSlot()
|
||||
def on_gauss_bt_edited(self):
|
||||
self.current_modulator.gauss_bt = self.ui.spinBoxGaussBT.value()
|
||||
self.draw_modulated()
|
||||
|
||||
@pyqtSlot()
|
||||
def on_gaus_filter_wdith_edited(self):
|
||||
self.current_modulator.gauss_filter_width = self.ui.spinBoxGaussFilterWidth.value()
|
||||
self.draw_modulated()
|
||||
|
||||
@pyqtSlot()
|
||||
def on_modulation_type_changed(self):
|
||||
if self.current_modulator.modulation_type == self.ui.comboBoxModulationType.currentIndex():
|
||||
if self.current_modulator.modulation_type_str == self.__cur_selected_mod_type():
|
||||
write_standard_parameters = False
|
||||
else:
|
||||
self.current_modulator.modulation_type = self.ui.comboBoxModulationType.currentIndex()
|
||||
self.current_modulator.modulation_type_str = self.__cur_selected_mod_type()
|
||||
write_standard_parameters = True
|
||||
|
||||
if self.ui.comboBoxModulationType.currentIndex() == 0:
|
||||
self.__set_gauss_ui_visibility(self.__cur_selected_mod_type() == "GFSK")
|
||||
|
||||
if self.__cur_selected_mod_type() == "ASK":
|
||||
self.ui.lParameterfor0.setText(self.tr("Amplitude for 0:"))
|
||||
self.ui.lParameterfor1.setText(self.tr("Amplitude for 1:"))
|
||||
self.ui.spinBoxParameter0.auto_suffix = False
|
||||
@@ -211,7 +236,7 @@ class ModulatorDialogController(QDialog):
|
||||
self.ui.spinBoxParameter0.setValue(self.current_modulator.param_for_zero)
|
||||
self.ui.spinBoxParameter1.setValue(self.current_modulator.param_for_one)
|
||||
|
||||
elif self.ui.comboBoxModulationType.currentIndex() == 1:
|
||||
elif self.__cur_selected_mod_type() in ("FSK", "GFSK"):
|
||||
self.ui.spinBoxParameter0.auto_suffix = True
|
||||
self.ui.spinBoxParameter1.auto_suffix = True
|
||||
self.ui.lParameterfor0.setText(self.tr("Frequency for 0:"))
|
||||
@@ -219,18 +244,16 @@ class ModulatorDialogController(QDialog):
|
||||
self.ui.spinBoxParameter0.setMaximum(1e12)
|
||||
self.ui.spinBoxParameter0.setMinimum(-1e12)
|
||||
self.ui.spinBoxParameter0.setDecimals(4)
|
||||
self.ui.spinBoxParameter0.setSuffix("")
|
||||
self.ui.spinBoxParameter1.setMaximum(1e12)
|
||||
self.ui.spinBoxParameter1.setMinimum(-1e12)
|
||||
self.ui.spinBoxParameter1.setDecimals(4)
|
||||
self.ui.spinBoxParameter1.setSuffix("")
|
||||
if write_standard_parameters:
|
||||
self.autodetect_fsk_freqs()
|
||||
else:
|
||||
self.ui.spinBoxParameter0.setValue(self.current_modulator.param_for_zero)
|
||||
self.ui.spinBoxParameter1.setValue(self.current_modulator.param_for_one)
|
||||
|
||||
elif self.ui.comboBoxModulationType.currentIndex() == 2:
|
||||
elif self.__cur_selected_mod_type() == "PSK":
|
||||
self.ui.spinBoxParameter0.auto_suffix = False
|
||||
self.ui.spinBoxParameter1.auto_suffix = False
|
||||
self.ui.lParameterfor0.setText(self.tr("Phase (degree) for 0:"))
|
||||
@@ -250,7 +273,8 @@ class ModulatorDialogController(QDialog):
|
||||
self.ui.spinBoxParameter0.setValue(self.current_modulator.param_for_zero)
|
||||
self.ui.spinBoxParameter1.setValue(self.current_modulator.param_for_one)
|
||||
|
||||
self.draw_modulated()
|
||||
self.ui.spinBoxParameter0.editingFinished.emit()
|
||||
self.ui.spinBoxParameter1.editingFinished.emit()
|
||||
|
||||
|
||||
def resizeEvent(self, event: QResizeEvent):
|
||||
@@ -327,6 +351,7 @@ class ModulatorDialogController(QDialog):
|
||||
|
||||
@pyqtSlot()
|
||||
def on_custom_modulation_index_changed(self):
|
||||
self.set_ui_for_current_modulator()
|
||||
self.draw_carrier()
|
||||
self.draw_data_bits()
|
||||
self.draw_modulated()
|
||||
@@ -472,7 +497,7 @@ class ModulatorDialogController(QDialog):
|
||||
self.autodetect_fsk_freqs()
|
||||
|
||||
def autodetect_fsk_freqs(self):
|
||||
if self.ui.comboBoxModulationType.currentIndex() != 1:
|
||||
if self.__cur_selected_mod_type() not in ("FSK", "GFSK"):
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -530,3 +555,13 @@ class ModulatorDialogController(QDialog):
|
||||
@pyqtSlot(int)
|
||||
def on_original_selection_changed(self, new_width: int):
|
||||
self.ui.lOriginalSignalSamplesSelected.setText(str(abs(new_width)))
|
||||
|
||||
|
||||
def __set_gauss_ui_visibility(self, show:bool):
|
||||
self.ui.lGaussBT.setVisible(show)
|
||||
self.ui.lGaussWidth.setVisible(show)
|
||||
self.ui.spinBoxGaussBT.setVisible(show)
|
||||
self.ui.spinBoxGaussFilterWidth.setVisible(show)
|
||||
|
||||
self.ui.spinBoxGaussFilterWidth.setValue(self.current_modulator.gauss_filter_width)
|
||||
self.ui.spinBoxGaussBT.setValue(self.current_modulator.gauss_bt)
|
||||
@@ -1,6 +1,6 @@
|
||||
import numpy
|
||||
from PyQt5.QtCore import Qt, pyqtSlot
|
||||
from PyQt5.QtWidgets import QDialog, QApplication
|
||||
from PyQt5.QtCore import Qt, pyqtSlot, QModelIndex
|
||||
from PyQt5.QtWidgets import QDialog, QApplication, QInputDialog
|
||||
|
||||
from urh import constants
|
||||
from urh.models.PLabelTableModel import PLabelTableModel
|
||||
@@ -30,9 +30,6 @@ class ProtocolLabelController(QDialog):
|
||||
self.ui.tblViewProtoLabels.setItemDelegateForColumn(1, SpinBoxDelegate(1, maxval, self))
|
||||
self.ui.tblViewProtoLabels.setItemDelegateForColumn(2, SpinBoxDelegate(1, maxval, self))
|
||||
self.ui.tblViewProtoLabels.setItemDelegateForColumn(3, CheckBoxDelegate(self))
|
||||
self.ui.tblViewProtoLabels.setItemDelegateForColumn(4, SpinBoxDelegate(offset+1,
|
||||
offset+proto_group.num_blocks,
|
||||
self))
|
||||
|
||||
self.ui.tblViewProtoLabels.setItemDelegateForColumn(5,
|
||||
ComboBoxDelegate([""] * len(constants.LABEL_COLORS), True,
|
||||
@@ -57,6 +54,7 @@ class ProtocolLabelController(QDialog):
|
||||
self.ui.btnConfirm.clicked.connect(self.confirm)
|
||||
self.ui.cbProtoView.currentIndexChanged.connect(self.set_view_index)
|
||||
self.model.restrictive_changed.connect(self.handle_restrictive_changed)
|
||||
self.ui.tblViewProtoLabels.clicked.connect(self.on_table_clicked)
|
||||
|
||||
@pyqtSlot()
|
||||
def confirm(self):
|
||||
@@ -67,21 +65,30 @@ class ProtocolLabelController(QDialog):
|
||||
self.ui.tblViewProtoLabels.openPersistentEditor(self.model.index(row, 2))
|
||||
self.ui.tblViewProtoLabels.openPersistentEditor(self.model.index(row, 3))
|
||||
|
||||
if self.model.protocol_labels[row].restrictive:
|
||||
self.ui.tblViewProtoLabels.openPersistentEditor(self.model.index(row, 4))
|
||||
|
||||
self.ui.tblViewProtoLabels.openPersistentEditor(self.model.index(row, 5))
|
||||
self.ui.tblViewProtoLabels.openPersistentEditor(self.model.index(row, 6))
|
||||
self.ui.tblViewProtoLabels.openPersistentEditor(self.model.index(row, 7))
|
||||
|
||||
@pyqtSlot(int, bool)
|
||||
def handle_restrictive_changed(self, row: int, restrictive: bool):
|
||||
if restrictive:
|
||||
self.ui.tblViewProtoLabels.openPersistentEditor(self.model.index(row, 4))
|
||||
else:
|
||||
self.ui.tblViewProtoLabels.closePersistentEditor(self.model.index(row, 4))
|
||||
self.model.update()
|
||||
|
||||
@pyqtSlot(int)
|
||||
def set_view_index(self, ind):
|
||||
self.model.proto_view = ind
|
||||
self.model.update()
|
||||
self.model.update()
|
||||
|
||||
@pyqtSlot(QModelIndex)
|
||||
def on_table_clicked(self, index: QModelIndex):
|
||||
if not index.isValid():
|
||||
return
|
||||
|
||||
i = index.row()
|
||||
lbl = self.model.protocol_labels[i]
|
||||
j = index.column()
|
||||
if j == 4 and lbl.restrictive:
|
||||
seqs, indexes = self.model.get_protocol_sequences(lbl.start, lbl.end)
|
||||
item, ok = QInputDialog.getItem(self, "Choose matching pattern", "Pattern", seqs)
|
||||
if ok and item:
|
||||
self.model.set_refblock(lbl, indexes[seqs.index(item)])
|
||||
self.model.update()
|
||||
|
||||
@@ -158,6 +158,7 @@ class SendRecvDialogController(QDialog):
|
||||
self.device.frequency = self.ui.spinBoxFreq.value()
|
||||
if self.mode == Mode.spectrum:
|
||||
self.scene_creator.scene.center_freq = self.ui.spinBoxFreq.value()
|
||||
self.scene_creator.clear_path()
|
||||
|
||||
@pyqtSlot()
|
||||
def on_bw_changed(self):
|
||||
|
||||
@@ -1021,13 +1021,6 @@ class SignalFrameController(QFrame):
|
||||
self.ui.btnSaveSignal.hide()
|
||||
self.ui.lineEditSignalName.setFont(font)
|
||||
|
||||
def redraw_after_resize(self):
|
||||
if self.ui.gvSignal.view_rect().width() > self.ui.gvSignal.sceneRect().width():
|
||||
x_factor = self.ui.gvSignal.width() / self.ui.gvSignal.sceneRect().width()
|
||||
self.ui.gvSignal.scale(x_factor / self.ui.gvSignal.transform().m11(), 1)
|
||||
|
||||
self.ui.gvSignal.autofit_view()
|
||||
|
||||
def contextMenuEvent(self, event: QContextMenuEvent):
|
||||
if self.signal is None:
|
||||
return
|
||||
|
||||
@@ -148,7 +148,6 @@ class SignalTabController(QWidget):
|
||||
sig_frame.files_dropped.connect(self.handle_files_dropped)
|
||||
sig_frame.apply_to_all_clicked.connect(self.handle_apply_to_all_clicked)
|
||||
sig_frame.sort_action_clicked.connect(self.sort_frames_by_name)
|
||||
self.splitter.splitterMoved.connect(sig_frame.redraw_after_resize)
|
||||
|
||||
|
||||
if prev_signal_frame is not None:
|
||||
|
||||
@@ -7,7 +7,7 @@ from urh.signalprocessing.ProtocolGroup import ProtocolGroup
|
||||
|
||||
class PLabelTableModel(QAbstractTableModel):
|
||||
header_labels = ["Name", "Start", "End", 'Match exactly',
|
||||
"Matching Block", 'Color', 'Apply decoding', 'Delete']
|
||||
"Matching sequence", 'Color', 'Apply decoding', 'Delete']
|
||||
|
||||
restrictive_changed = pyqtSignal(int, bool)
|
||||
label_removed = pyqtSignal(ProtocolLabel)
|
||||
@@ -56,7 +56,15 @@ class PLabelTableModel(QAbstractTableModel):
|
||||
return lbl.restrictive
|
||||
elif j == 4:
|
||||
if lbl.restrictive:
|
||||
return lbl.refblock + self.offset + 1
|
||||
start = int(self.proto_group.convert_index(lbl.start, 0, self.proto_view, True)[0])
|
||||
end = int(self.proto_group.convert_index(lbl.end, 0, self.proto_view, True)[1])
|
||||
block = self.proto_group.blocks[lbl.refblock]
|
||||
if self.proto_view == 0:
|
||||
return block.decoded_bits_str[start:end]
|
||||
elif self.proto_view == 1:
|
||||
return block.decoded_hex_str[start:end]
|
||||
else:
|
||||
return block.decoded_ascii_str[start:end]
|
||||
else:
|
||||
return "-"
|
||||
elif j == 5:
|
||||
@@ -99,9 +107,8 @@ class PLabelTableModel(QAbstractTableModel):
|
||||
self.restrictive_changed.emit(i, value)
|
||||
lbl.find_block_numbers(proto)
|
||||
elif j == 4:
|
||||
lbl.refblock = int(value) - self.offset - 1
|
||||
lbl.reference_bits = proto[lbl.refblock][lbl.start:lbl.end]
|
||||
lbl.find_block_numbers(proto)
|
||||
# Pass Reference bits via seperate dialog
|
||||
pass
|
||||
elif j == 5:
|
||||
lbl.color_index = value
|
||||
elif j == 6:
|
||||
@@ -111,6 +118,13 @@ class PLabelTableModel(QAbstractTableModel):
|
||||
|
||||
return True
|
||||
|
||||
def set_refblock(self, lbl: ProtocolLabel, refblock: int):
|
||||
proto = self.proto_group.decoded_bits_str
|
||||
lbl.refblock = int(refblock) - self.offset
|
||||
lbl.reference_bits = proto[lbl.refblock][lbl.start:lbl.end]
|
||||
lbl.find_block_numbers(proto)
|
||||
|
||||
|
||||
def flags(self, index):
|
||||
if not index.isValid():
|
||||
return Qt.NoItemFlags
|
||||
@@ -121,11 +135,35 @@ class PLabelTableModel(QAbstractTableModel):
|
||||
return Qt.NoItemFlags
|
||||
|
||||
if index.column() == 4 and not lbl.restrictive:
|
||||
return Qt.ItemIsSelectable
|
||||
return Qt.NoItemFlags
|
||||
elif index.column() == 4 and lbl.restrictive:
|
||||
return Qt.ItemIsSelectable | Qt.ItemIsEnabled
|
||||
|
||||
return Qt.ItemIsEditable | Qt.ItemIsEnabled
|
||||
|
||||
def remove_label(self, label):
|
||||
self.proto_group.remove_label(label)
|
||||
self.update()
|
||||
self.label_removed.emit(label)
|
||||
self.label_removed.emit(label)
|
||||
|
||||
def get_protocol_sequences(self, start: int, end: int):
|
||||
sequences = []
|
||||
indexes = []
|
||||
start = int(self.proto_group.convert_index(start, 0, self.proto_view, True)[0])
|
||||
end = int(self.proto_group.convert_index(end, 0, self.proto_view, True)[0])
|
||||
|
||||
for i, block in enumerate(self.proto_group.blocks):
|
||||
|
||||
if self.proto_view == 0:
|
||||
data = block.decoded_bits_str[start:end]
|
||||
elif self.proto_view == 1:
|
||||
data = block.decoded_hex_str[start:end]
|
||||
else:
|
||||
data = block.decoded_ascii_str[start:end]
|
||||
|
||||
if len(data) == end - start and data not in sequences:
|
||||
sequences.append(data)
|
||||
indexes.append(i) # For setting refblock later
|
||||
|
||||
return sequences, indexes
|
||||
|
||||
|
||||
@@ -121,11 +121,15 @@ class ProtocolTreeModel(QAbstractItemModel):
|
||||
return QIcon.fromTheme("folder")
|
||||
elif role == Qt.CheckStateRole:
|
||||
return item.show
|
||||
elif role == Qt.FontRole and item.is_group and\
|
||||
self.rootItem.index_of(item) in self.controller.active_group_ids:
|
||||
font = QFont()
|
||||
font.setBold(True)
|
||||
return font
|
||||
elif role == Qt.FontRole:
|
||||
if item.is_group and self.rootItem.index_of(item) in self.controller.active_group_ids:
|
||||
font = QFont()
|
||||
font.setBold(True)
|
||||
return font
|
||||
elif item.protocol in self.controller.selected_protocols:
|
||||
font = QFont()
|
||||
font.setBold(True)
|
||||
return font
|
||||
elif role == Qt.TextColorRole and item.protocol == self.reference_protocol:
|
||||
return constants.SELECTED_ROW_COLOR
|
||||
elif role == Qt.ToolTipRole:
|
||||
|
||||
@@ -120,14 +120,13 @@ class TableModel(QAbstractTableModel):
|
||||
|
||||
offset = 0
|
||||
for group in self.controller.groups:
|
||||
if group in self.controller.active_groups:
|
||||
for lbl in group.labels:
|
||||
bg_color = label_colors[lbl.color_index]
|
||||
for i in lbl.block_numbers:
|
||||
start, end = group.get_label_range(lbl, self.proto_view, self.decode)
|
||||
for j in range(start, end):
|
||||
self.background_colors[i+offset, j] = bg_color
|
||||
self.tooltips[i+offset, j] = lbl.name
|
||||
for lbl in group.labels:
|
||||
bg_color = label_colors[lbl.color_index]
|
||||
for i in lbl.block_numbers:
|
||||
start, end = group.get_label_range(lbl, self.proto_view, self.decode)
|
||||
for j in range(start, end):
|
||||
self.background_colors[i+offset, j] = bg_color
|
||||
self.tooltips[i+offset, j] = lbl.name
|
||||
offset += group.num_blocks
|
||||
|
||||
def refresh_fonts(self):
|
||||
|
||||
@@ -10,13 +10,13 @@ from urh.cythonext import path_creator
|
||||
from urh.cythonext.signalFunctions import Symbol
|
||||
from urh.ui.ZoomableScene import ZoomableScene
|
||||
|
||||
|
||||
class Modulator(object):
|
||||
"""
|
||||
This class can modulate bits to a carrier.
|
||||
Very useful in generation phase.
|
||||
"""
|
||||
MODULATION_TYPES = ["ASK", "FSK", "PSK"]
|
||||
|
||||
MODULATION_TYPES = ["ASK", "FSK", "PSK", "GFSK"]
|
||||
|
||||
|
||||
def __init__(self, name: str):
|
||||
@@ -30,6 +30,9 @@ class Modulator(object):
|
||||
self.modulation_type = 0
|
||||
self.name = name
|
||||
|
||||
self.gauss_bt = 0.5 # bt product for gaussian filter (GFSK)
|
||||
self.gauss_filter_width = 1 # filter width for gaussian filter (GFSK)
|
||||
|
||||
self.param_for_zero = 0 # Freq, Amplitude (0..100%) or Phase (0..360)
|
||||
self.param_for_one = 100 # Freq, Amplitude (0..100%) or Phase (0..360)
|
||||
|
||||
@@ -85,12 +88,18 @@ class Modulator(object):
|
||||
def modulation_type_str(self):
|
||||
return self.MODULATION_TYPES[self.modulation_type]
|
||||
|
||||
@modulation_type_str.setter
|
||||
def modulation_type_str(self, val: str):
|
||||
val = val.upper()
|
||||
if val in self.MODULATION_TYPES:
|
||||
self.modulation_type = self.MODULATION_TYPES.index(val)
|
||||
|
||||
@property
|
||||
def param_for_zero_str(self):
|
||||
mod = self.MODULATION_TYPES[self.modulation_type]
|
||||
if mod == "ASK":
|
||||
return str(self.param_for_zero) + "%"
|
||||
elif mod == "FSK":
|
||||
elif mod == "FSK" or mod == "GFSK":
|
||||
return self.get_value_with_suffix(self.param_for_zero) + "Hz"
|
||||
elif mod == "PSK":
|
||||
return str(self.param_for_zero) + "°"
|
||||
@@ -100,7 +109,7 @@ class Modulator(object):
|
||||
mod = self.MODULATION_TYPES[self.modulation_type]
|
||||
if mod == "ASK":
|
||||
return str(self.param_for_one) + "%"
|
||||
elif mod == "FSK":
|
||||
elif mod == "FSK" or mod == "GFSK":
|
||||
return self.get_value_with_suffix(self.param_for_one) + "Hz"
|
||||
elif mod == "PSK":
|
||||
return str(self.param_for_one) + "°"
|
||||
@@ -161,19 +170,57 @@ class Modulator(object):
|
||||
log_bit = bit
|
||||
samples_per_bit = self.samples_per_bit
|
||||
|
||||
param = self.param_for_one if log_bit else self.param_for_zero
|
||||
if mod_type == "FSK" or mod_type == "GFSK":
|
||||
param = 1 if log_bit else -1
|
||||
else:
|
||||
param = self.param_for_one if log_bit else self.param_for_zero
|
||||
paramvector[sample_pos:sample_pos + samples_per_bit] = np.full(samples_per_bit, param, dtype=np.float64)
|
||||
sample_pos += samples_per_bit
|
||||
|
||||
t = np.arange(start, start + total_samples - pause) / self.sample_rate
|
||||
a = paramvector / 100 if mod_type == "ASK" else self.carrier_amplitude
|
||||
phi = paramvector * (np.pi / 180) if mod_type == "PSK" else self.carrier_phase_deg * (np.pi / 180)
|
||||
f = paramvector if mod_type == "FSK" else self.carrier_freq_hz
|
||||
|
||||
if mod_type == "FSK" or mod_type == "GFSK":
|
||||
fmid = (self.param_for_one + self.param_for_zero)/2
|
||||
dist = abs(fmid - self.param_for_one)
|
||||
if mod_type == "GFSK":
|
||||
gfir = self.gauss_fir(bt=self.gauss_bt, filter_width=self.gauss_filter_width)
|
||||
if len(paramvector) >= len(gfir):
|
||||
paramvector = np.convolve(paramvector, gfir, mode="same")
|
||||
else:
|
||||
# Prevent dimension crash later, because gaussian finite impulse response is longer then paramvector
|
||||
paramvector = np.convolve(gfir, paramvector, mode="same")[:len(paramvector)]
|
||||
|
||||
f = fmid + dist * paramvector
|
||||
|
||||
# sin(2*pi*f_1*t_1 + phi_1) = sin(2*pi*f_2*t_1 + phi_2) <=> phi_2 = 2*pi*t_1*(f_1 - f_2) + phi_1
|
||||
phi = np.empty(len(f))
|
||||
phi[0] = self.carrier_phase_deg
|
||||
for i in range(0, len(phi) - 1):
|
||||
phi[i+1] = 2 * np.pi * t[i] * (f[i]-f[i+1]) + phi[i] # Correct the phase to prevent spiky jumps
|
||||
else:
|
||||
f = self.carrier_freq_hz
|
||||
|
||||
self.modulated_samples.imag[:total_samples - pause] = a * np.sin(2 * np.pi * f * t + phi)
|
||||
self.modulated_samples.real[:total_samples - pause] = a * np.cos(2 * np.pi * f * t + phi)
|
||||
|
||||
|
||||
def gauss_fir(self, bt=0.5, filter_width=1):
|
||||
"""
|
||||
|
||||
:param bt: normalized 3-dB bandwidth-symbol time product
|
||||
:param span: filter span in symbols
|
||||
:return:
|
||||
"""
|
||||
# http://onlinelibrary.wiley.com/doi/10.1002/9780470041956.app2/pdf
|
||||
k = np.arange(-int(filter_width * self.samples_per_bit), int(filter_width * self.samples_per_bit)+1)
|
||||
ts = self.samples_per_bit / self.sample_rate # symbol time
|
||||
#a = np.sqrt(np.log(2)/2)*(ts/bt)
|
||||
#B = a / np.sqrt(np.log(2)/2) # filter bandwidth
|
||||
h = np.sqrt((2*np.pi)/(np.log(2))) * bt/ts * np.exp(-(((np.sqrt(2)*np.pi)/np.sqrt(np.log(2))*bt*k/self.samples_per_bit)**2))
|
||||
return h / h.sum()
|
||||
|
||||
@staticmethod
|
||||
def get_value_with_suffix(value):
|
||||
if abs(value) >= 10 ** 9:
|
||||
|
||||
@@ -94,7 +94,7 @@ class ProtocolAnalyzerContainer(ProtocolAnalyzer):
|
||||
l.refblock += proto_analyzer.num_blocks
|
||||
|
||||
for p in proto_labels:
|
||||
self.__group.add_label(p)
|
||||
self.__group.add_label(p, decode=False)
|
||||
|
||||
for block in self.blocks:
|
||||
block.fuzz_labels[index:0] = [p for p in proto_labels if p not in block.fuzz_labels]
|
||||
@@ -114,7 +114,7 @@ class ProtocolAnalyzerContainer(ProtocolAnalyzer):
|
||||
self.qt_signals.line_duplicated.emit()
|
||||
|
||||
def refresh_protolabel_blocks(self):
|
||||
self.__group.refresh_labels()
|
||||
self.__group.refresh_labels(decode=False)
|
||||
|
||||
def fuzz_successive(self):
|
||||
"""
|
||||
|
||||
@@ -110,17 +110,20 @@ class ProtocolGroup(object):
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def refresh_label(self, lbl: ProtocolLabel):
|
||||
def refresh_label(self, lbl: ProtocolLabel, decode=True):
|
||||
if lbl not in self.labels:
|
||||
print("Label {0} is not in Group {1}".format(lbl.name, self.name), file=sys.stderr)
|
||||
return
|
||||
|
||||
lbl.find_block_numbers(self.decoded_bits_str)
|
||||
if decode:
|
||||
lbl.find_block_numbers(self.decoded_bits_str)
|
||||
else:
|
||||
lbl.find_block_numbers(self.plain_bits_str)
|
||||
|
||||
def refresh_labels(self):
|
||||
def refresh_labels(self, decode=True):
|
||||
for lbl in self.labels:
|
||||
#lbl.signals.apply_decoding_changed.emit(lbl) # Update DnD Labels for new blocks
|
||||
self.refresh_label(lbl)
|
||||
self.refresh_label(lbl, decode)
|
||||
|
||||
def convert_index(self, index: int, from_view: int, to_view: int, decoded: bool, block_indx=-1) -> tuple:
|
||||
"""
|
||||
@@ -224,12 +227,12 @@ class ProtocolGroup(object):
|
||||
|
||||
return proto_label
|
||||
|
||||
def add_label(self, lbl: ProtocolLabel, refresh=True):
|
||||
def add_label(self, lbl: ProtocolLabel, refresh=True, decode=True):
|
||||
if lbl not in self.labels:
|
||||
lbl.signals.apply_decoding_changed.connect(self.handle_plabel_apply_decoding_changed)
|
||||
self.labels.append(lbl)
|
||||
if refresh:
|
||||
self.refresh_label(lbl)
|
||||
self.refresh_label(lbl, decode=decode)
|
||||
self.labels.sort()
|
||||
|
||||
def handle_plabel_apply_decoding_changed(self, lbl: ProtocolLabel):
|
||||
|
||||
@@ -46,13 +46,20 @@ class GridScene(ZoomableScene):
|
||||
painter.scale(scale_x, scale_y)
|
||||
|
||||
font_height = self.font_metrics.height()
|
||||
counter = -1 # Counter for Label for every second line
|
||||
|
||||
for x in x_range:
|
||||
freq = self.frequencies[x]
|
||||
counter += 1
|
||||
|
||||
if freq != 0 and (counter % 2 != 0): # Label for every second line
|
||||
continue
|
||||
|
||||
if freq != 0:
|
||||
prefix = "+" if freq > 0 else ""
|
||||
value = prefix+Formatter.big_value_with_suffix(freq)
|
||||
value = prefix+Formatter.big_value_with_suffix(freq, 2)
|
||||
else:
|
||||
counter = 0
|
||||
value = Formatter.big_value_with_suffix(self.center_freq)
|
||||
font_width = self.font_metrics.width(value)
|
||||
painter.drawText(x / scale_x - font_width / 2,
|
||||
|
||||
@@ -22,12 +22,10 @@ class KillerDoubleSpinBox(QDoubleSpinBox):
|
||||
if self.suffix() != text[-1]:
|
||||
if self.auto_suffix:
|
||||
self.setSuffix(text[-1])
|
||||
self.on_text_edited()
|
||||
else:
|
||||
if self.suffix() != "":
|
||||
if self.auto_suffix:
|
||||
self.setSuffix("")
|
||||
self.on_text_edited()
|
||||
|
||||
def on_text_edited(self):
|
||||
self.lineEdit().setText(self.lineEdit().text().upper())
|
||||
@@ -39,7 +37,6 @@ class KillerDoubleSpinBox(QDoubleSpinBox):
|
||||
|
||||
def setUnit(self):
|
||||
value = abs(self.value())
|
||||
|
||||
if 10 ** 9 <= value <= 10 ** 11:
|
||||
if self.suffix() != "G" and self.auto_suffix:
|
||||
self.setSuffix("G")
|
||||
@@ -85,6 +82,6 @@ class KillerDoubleSpinBox(QDoubleSpinBox):
|
||||
return super().valueFromText(text)
|
||||
|
||||
def validate(self, inpt: str, pos: int):
|
||||
rx = QRegExp("^(-?[0-9]+)[.]?[0-9]*[kKmMgG]?$")
|
||||
rx = QRegExp("^(-?[0-9]+)[.]?[0-9]*[kKmMgG"+str(self.suffix())+"]?$")
|
||||
result = QValidator.Acceptable if rx.exactMatch(inpt.replace(",", ".")) else QValidator.Invalid
|
||||
return result, inpt, pos
|
||||
|
||||
@@ -223,6 +223,7 @@ class EpicGraphicView(SelectableGraphicView):
|
||||
self.resetTransform()
|
||||
x_factor = self.width() / self.sceneRect().width()
|
||||
self.scale(x_factor, y_factor)
|
||||
self.centerOn(0, self.y_center)
|
||||
|
||||
def zoom_to_selection(self, start: int, end: int):
|
||||
if start == end:
|
||||
@@ -249,4 +250,12 @@ class EpicGraphicView(SelectableGraphicView):
|
||||
self.zoom_all_signals(0.9)
|
||||
|
||||
def clear_selection(self):
|
||||
self.set_selection_area(0, 0)
|
||||
self.set_selection_area(0, 0)
|
||||
|
||||
|
||||
def resizeEvent(self, event):
|
||||
if self.view_rect().width() > self.sceneRect().width():
|
||||
x_factor = self.width() / self.sceneRect().width()
|
||||
self.scale(x_factor / self.transform().m11(), 1)
|
||||
|
||||
self.autofit_view()
|
||||
@@ -42,13 +42,10 @@ class LiveGraphicView(QGraphicsView):
|
||||
self.zoomed.emit(zoom_factor)
|
||||
|
||||
def mouseMoveEvent(self, event: QMouseEvent):
|
||||
try:
|
||||
if isinstance(self.scene(), GridScene):
|
||||
freq = self.scene().get_freq_for_pos(int(self.mapToScene(event.pos()).x()))
|
||||
if freq is not None:
|
||||
QToolTip.showText(self.mapToGlobal(event.pos()), Formatter.big_value_with_suffix(freq), None, QRect(), 10000)
|
||||
except TypeError:
|
||||
pass # Frequency not ready yet
|
||||
if isinstance(self.scene(), GridScene):
|
||||
freq = self.scene().get_freq_for_pos(int(self.mapToScene(event.pos()).x()))
|
||||
if freq is not None:
|
||||
QToolTip.showText(self.mapToGlobal(event.pos()), "Tune to:"+Formatter.big_value_with_suffix(freq), None, QRect(), 10000)
|
||||
|
||||
def mousePressEvent(self, event: QMouseEvent):
|
||||
if isinstance(self.scene(), GridScene):
|
||||
|
||||
@@ -22,12 +22,13 @@ class Formatter():
|
||||
return locale.format_string("%.2f " + suffix, value) + "s"
|
||||
|
||||
@staticmethod
|
||||
def big_value_with_suffix(value: float) -> str:
|
||||
def big_value_with_suffix(value: float, decimals=3) -> str:
|
||||
fmt_str = "%.{0:d}f".format(decimals)
|
||||
if abs(value) >= 1e9:
|
||||
return locale.format_string("%.3fG", value / 1e9)
|
||||
return locale.format_string(fmt_str+"G", value / 1e9)
|
||||
elif abs(value) >= 1e6:
|
||||
return locale.format_string("%.3fM", value / 1e6)
|
||||
return locale.format_string(fmt_str+"M", value / 1e6)
|
||||
elif abs(value) >= 1e3:
|
||||
return locale.format_string("%.3fK", value / 1e3)
|
||||
return locale.format_string(fmt_str+"K", value / 1e3)
|
||||
else:
|
||||
return locale.format_string("%.3f", value)
|
||||
return locale.format_string(fmt_str, value)
|
||||
|
||||
60
tests/GFSK.py
Normal file
60
tests/GFSK.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import copy
|
||||
import unittest
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
from urh.signalprocessing.Modulator import Modulator
|
||||
from urh.signalprocessing.ProtocolAnalyzer import ProtocolAnalyzer
|
||||
from urh.signalprocessing.Signal import Signal
|
||||
from urh.cythonext import signalFunctions
|
||||
|
||||
class GFSK(unittest.TestCase):
|
||||
def test_plot(self):
|
||||
modulator = Modulator("gfsk")
|
||||
modulator.modulation_type_str = "GFSK"
|
||||
modulator.samples_per_bit = 100
|
||||
modulator.sample_rate = 1e6
|
||||
modulator.param_for_one = 20e3
|
||||
modulator.param_for_zero = 10e3
|
||||
modulator.carrier_freq_hz = 15e3
|
||||
modulator.carrier_phase_deg = 90
|
||||
|
||||
|
||||
modulator.modulate([True, False, True, False, False], 77)
|
||||
data = copy.deepcopy(modulator.modulated_samples)
|
||||
modulator.modulate([False, True, True, True, True, False, True], 100, start=len(data))
|
||||
data = np.concatenate((data, modulator.modulated_samples))
|
||||
|
||||
plt.subplot(2, 1, 1)
|
||||
axes = plt.gca()
|
||||
axes.set_ylim([-2,2])
|
||||
plt.plot(data.real)
|
||||
plt.title("Modulated Wave")
|
||||
|
||||
plt.subplot(2, 1, 2)
|
||||
qad = signalFunctions.afp_demod(np.ascontiguousarray(data), 0, 1)
|
||||
plt.plot(qad)
|
||||
plt.title("Quad Demod")
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
def test_gfsk(self):
|
||||
modulator = Modulator("gfsk")
|
||||
modulator.modulation_type_str = "FSK"
|
||||
modulator.samples_per_bit = 100
|
||||
modulator.sample_rate = 1e6
|
||||
modulator.param_for_one = 20e3
|
||||
modulator.param_for_zero = -10e3
|
||||
modulator.modulate([True, False, False, True, False], 9437)
|
||||
s = modulator.modulated_samples
|
||||
modulator.modulate([True, False, True], 9845) #, start=len(s))
|
||||
s = np.concatenate((s, modulator.modulated_samples))
|
||||
modulator.modulate([True, False, True, False], 8457) #, start=len(s))
|
||||
s = np.concatenate((s, modulator.modulated_samples))
|
||||
|
||||
s.tofile("/tmp/test.complex")
|
||||
|
||||
pa = ProtocolAnalyzer(Signal("/tmp/test.complex", "test", modulation="FSK"))
|
||||
pa.get_protocol_from_signal()
|
||||
@@ -1,26 +0,0 @@
|
||||
import os
|
||||
import unittest
|
||||
from urh import constants
|
||||
|
||||
from urh.signalprocessing.ProtocolAnalyzer import ProtocolAnalyzer
|
||||
from urh.signalprocessing.ProtocolBlock import ProtocolBlock
|
||||
from urh.signalprocessing.encoding import encoding
|
||||
|
||||
|
||||
class TestLoadProtocolFile(unittest.TestCase):
|
||||
# Testmethode muss immer mit Präfix test_* starten
|
||||
def test_proto_block_from_str(self):
|
||||
bits = "1011AB11"
|
||||
pb = ProtocolBlock.from_plain_bits_str(bits)
|
||||
self.assertEqual(bits, pb.plain_bits_str)
|
||||
|
||||
# def test_proto_analyzer_from_file(self):
|
||||
# # TODO Compareframe methode nutzen, auch testen ob Labels da sind
|
||||
# self.assertTrue(os.path.isfile("./data/protocol.txt"))
|
||||
# pa, view_type, encoding = ProtocolAnalyzer.from_file("./data/protocol.txt")
|
||||
# self.assertEqual(pa.blocks[0].plain_bits_str,
|
||||
# "10101010110100111011010111011101110111011100110001011101010001011101110110110101101")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
396
ui/modulation.ui
396
ui/modulation.ui
@@ -342,180 +342,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="KillerDoubleSpinBox" name="spinBoxParameter1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.990000009536743</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lParameterfor1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Amplitude for 1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lParameterfor0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Amplitude for 0:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="chkBoxLockSIV">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lock SIV to original signal</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QComboBox" name="comboBoxModulationType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Amplitude Shift Keying (ASK)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Frequency Shift Keying (FSK)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Phase Shift Keying (PSK)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="KillerDoubleSpinBox" name="spinBoxParameter0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.990000009536743</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lSamplesInViewModulatedText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Samples in View:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLabel" name="lSamplesInViewModulated">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Shown Samples in View:</p><p><span style=" font-weight:600; color:#ff0000;">Red</span> - if samples in view differ from original signal</p><p><span style=" font-weight:600;">Normal</span> - if samples in view are equal to the original signal</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>101010121</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Samples selected:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QLabel" name="lModulatedSelectedSamples">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="font">
|
||||
@@ -926,6 +752,228 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxGaussBT">
|
||||
<property name="minimum">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>0.990000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="KillerDoubleSpinBox" name="spinBoxParameter1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.990000009536743</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lParameterfor1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Amplitude for 1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lParameterfor0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Amplitude for 0:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="chkBoxLockSIV">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lock SIV to original signal</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QComboBox" name="comboBoxModulationType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Amplitude Shift Keying (ASK)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Frequency Shift Keying (FSK)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Gaussian Frequency Shift Keying (GFSK)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Phase Shift Keying (PSK)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="KillerDoubleSpinBox" name="spinBoxParameter0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.990000009536743</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lSamplesInViewModulatedText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Samples in View:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QLabel" name="lSamplesInViewModulated">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Shown Samples in View:</p><p><span style=" font-weight:600; color:#ff0000;">Red</span> - if samples in view differ from original signal</p><p><span style=" font-weight:600;">Normal</span> - if samples in view are equal to the original signal</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>101010121</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Samples selected:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="2">
|
||||
<widget class="QLabel" name="lModulatedSelectedSamples">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lGaussBT">
|
||||
<property name="text">
|
||||
<string>Gauss BT:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lGaussWidth">
|
||||
<property name="text">
|
||||
<string>Gauss filter width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxGaussFilterWidth">
|
||||
<property name="minimum">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>100.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -501,7 +501,7 @@
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -544,8 +544,19 @@
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>cbDevice</tabstop>
|
||||
<tabstop>lineEditIP</tabstop>
|
||||
<tabstop>spinBoxFreq</tabstop>
|
||||
<tabstop>spinBoxSampleRate</tabstop>
|
||||
<tabstop>spinBoxBandwidth</tabstop>
|
||||
<tabstop>spinBoxGain</tabstop>
|
||||
<tabstop>spinBoxNRepeat</tabstop>
|
||||
<tabstop>btnStart</tabstop>
|
||||
<tabstop>btnStop</tabstop>
|
||||
<tabstop>btnSave</tabstop>
|
||||
<tabstop>btnClear</tabstop>
|
||||
<tabstop>graphicsView</tabstop>
|
||||
<tabstop>sliderYscale</tabstop>
|
||||
<tabstop>txtEditErrors</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -67,26 +67,16 @@
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetFixedSize</enum>
|
||||
</property>
|
||||
<item row="12" column="0">
|
||||
<widget class="QPushButton" name="btnReplay">
|
||||
<property name="text">
|
||||
<string>Replay signal...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="media-playback-start">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QCheckBox" name="chkBoxShowProtocol">
|
||||
<item row="19" column="0">
|
||||
<widget class="QCheckBox" name="chkBoxSyncSelection">
|
||||
<property name="toolTip">
|
||||
<string>Show the extracted protocol based on the parameters InfoLen, PauseLen and ZeroTreshold (in QuadratureDemod-View).
|
||||
|
||||
If you want your protocol to be better seperated, edit the PauseLen using right-click menu from a selection in SignalView or ProtocolView.</string>
|
||||
<string>If this is set to true, your selected protocol bits will show up in the signal view, and vice versa.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Signal as</string>
|
||||
<string>Sync Selection</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -106,18 +96,17 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<item row="18" column="0">
|
||||
<widget class="QCheckBox" name="chkBoxShowProtocol">
|
||||
<property name="toolTip">
|
||||
<string>Show the extracted protocol based on the parameters InfoLen, PauseLen and ZeroTreshold (in QuadratureDemod-View).
|
||||
|
||||
If you want your protocol to be better seperated, edit the PauseLen using right-click menu from a selection in SignalView or ProtocolView.</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
<property name="text">
|
||||
<string>Show Signal as</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
@@ -201,6 +190,28 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxTolerance">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>This is the error tolerance for determining the <span style=" font-weight:600;">pulse lengths</span> in the demodulated signal.</p><p><span style=" text-decoration: underline;">Example:</span> Say, we are reading a ones pulse and the tolerance value was set to 5. Then 5 errors (which must follow sequentially) are accepted.</p><p>Tune this value if you have <span style=" font-weight:600;">spiky data</span> after demodulation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="lErrorTolerance">
|
||||
<property name="sizePolicy">
|
||||
@@ -229,7 +240,7 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="lSignalViewText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
@@ -239,7 +250,7 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<underline>true</underline>
|
||||
<underline>false</underline>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@@ -247,29 +258,7 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxTolerance">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>This is the error tolerance for determining the <span style=" font-weight:600;">pulse lengths</span> in the demodulated signal.</p><p><span style=" text-decoration: underline;">Example:</span> Say, we are reading a ones pulse and the tolerance value was set to 5. Then 5 errors (which must follow sequentially) are accepted.</p><p>Tune this value if you have <span style=" font-weight:600;">spiky data</span> after demodulation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<item row="18" column="1">
|
||||
<widget class="QComboBox" name="cbProtoView">
|
||||
<item>
|
||||
<property name="text">
|
||||
@@ -288,22 +277,9 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QCheckBox" name="chkBoxSyncSelection">
|
||||
<property name="toolTip">
|
||||
<string>If this is set to true, your selected protocol bits will show up in the signal view, and vice versa.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sync Selection</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="5">
|
||||
<item row="0" column="9">
|
||||
<widget class="QToolButton" name="btnMinimize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
@@ -374,7 +350,7 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<item row="0" column="10">
|
||||
<widget class="QToolButton" name="btnCloseSignal">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
@@ -441,7 +417,7 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<item row="0" column="6">
|
||||
<widget class="QToolButton" name="btnInfo">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@@ -464,6 +440,32 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QToolButton" name="btnReplay">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Replay signal</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="media-playback-start">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
@@ -528,7 +530,7 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="2">
|
||||
<item row="14" column="0" colspan="2">
|
||||
<widget class="QComboBox" name="cbSignalView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
@@ -566,13 +568,67 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Modulation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="labelModulation">
|
||||
<property name="text">
|
||||
<string>FSK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0" colspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="15" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnAutoDetect">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Automatically detect Center and Bit Length, when you change the demodulation type. You can disable this behaviour for faster switching between demodulations.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto-Detect</string>
|
||||
<string>Autodetect parameters</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="system-software-update">
|
||||
@@ -592,20 +648,6 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Modulation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="labelModulation">
|
||||
<property name="text">
|
||||
<string>FSK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -1086,10 +1128,13 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>btnMinimize</tabstop>
|
||||
<tabstop>btnSaveSignal</tabstop>
|
||||
<tabstop>btnInfo</tabstop>
|
||||
<tabstop>btnMinimize</tabstop>
|
||||
<tabstop>btnCloseSignal</tabstop>
|
||||
<tabstop>lineEditSignalName</tabstop>
|
||||
<tabstop>spinBoxNoiseTreshold</tabstop>
|
||||
<tabstop>spinBoxCenterOffset</tabstop>
|
||||
<tabstop>spinBoxInfoLen</tabstop>
|
||||
<tabstop>spinBoxTolerance</tabstop>
|
||||
<tabstop>cbSignalView</tabstop>
|
||||
@@ -1103,6 +1148,7 @@ If you want your protocol to be better seperated, edit the PauseLen using right-
|
||||
<tabstop>btnShowHideStartEnd</tabstop>
|
||||
<tabstop>spinBoxSelectionStart</tabstop>
|
||||
<tabstop>spinBoxSelectionEnd</tabstop>
|
||||
<tabstop>spinBoxXZoom</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../urh.qrc"/>
|
||||
|
||||
Reference in New Issue
Block a user