def updateObjectFilter(self):
        # -- Add message filter rows -- #
        font = self.getFont()
        self.filterTabs.clear()
        self.filterTabs.addTab(self.filterTable, 'Information ID')
        # For each object in objectList, create a new Table and add it to the tabs.
        for keys, values in Globals.objectDict.items():
            objectFilterTable = QTableWidget()
            objectFilterTable.setRowCount(0)
            objectFilterTable.setColumnCount(2)
            strSplit = keys + ';Enable'
            objectFilterTable.setHorizontalHeaderLabels(strSplit.split(';'))
            objectFilterTable.resizeColumnsToContents()
            filterTableHeader = objectFilterTable.horizontalHeader()
            filterTableHeader.setSectionResizeMode(0, QHeaderView.Stretch)
            filterTableHeader.setSectionResizeMode(
                1, QHeaderView.ResizeToContents)
            checkBoxFilter = self.createCheckBox()

            objectFilterTable.itemChanged.connect(
                lambda *a, table=objectFilterTable: self.filterAllObjectIDs(
                    *a, table=table))

            objectTableIndex = 0
            objectFilterTable.insertRow(objectTableIndex)
            objCat = QTableWidgetItem('FILTER ALL')
            objCat.setFont(font)
            objectFilterTable.setItem(objectTableIndex, 0, objCat)
            objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter)
            objectTableIndex = objectTableIndex + 1
            for keys2, values2 in values.items():
                objectFilterTable.insertRow(objectTableIndex)
                checkBoxFilter = self.createCheckBox()
                objectFilterTable.setItem(
                    objectTableIndex, 0,
                    QTableWidgetItem('ID: ' + str(keys2) + ' Name: ' +
                                     str(values2)))
                objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter)
                objectTableIndex = objectTableIndex + 1

            # Add the newly create table to the tabs.
            self.filterTabs.addTab(objectFilterTable, keys)
            self.objectTabDict[keys] = objectFilterTable
Beispiel #2
0
class ModelGroupsTable(QWidget):
    EditableAttrs = [
        attr for attr in PlotStyles.StyleAttributes
        if attr in PlotStyles.StyleAttributeOptions
    ]
    ColList = 3
    ColPlot = 4
    ColApply = 5
    AttrByCol = dict([(i + 6, attr) for i, attr in enumerate(EditableAttrs)])

    def __init__(self, parent, *args):
        QWidget.__init__(self, parent, *args)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        lo = QVBoxLayout(self)
        lo.setContentsMargins(0, 0, 0, 0)
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        lbl = QLabel(QString("<nobr><b>Source groupings:</b></nobr>"), self)
        lo1.addWidget(lbl, 0)
        lo1.addStretch(1)
        # add show/hide button
        self._showattrbtn = QPushButton(self)
        self._showattrbtn.setMinimumWidth(256)
        lo1.addWidget(self._showattrbtn, 0)
        lo1.addStretch()
        self._showattrbtn.clicked.connect(self._togglePlotControlsVisibility)
        # add table
        self.table = QTableWidget(self)
        lo.addWidget(self.table)
        self.table.cellChanged[int, int].connect(self._valueChanged)
        self.table.setSelectionMode(QTableWidget.NoSelection)
        # setup basic columns
        self.table.setColumnCount(6 + len(self.EditableAttrs))
        for i, label in enumerate(
            ("grouping", "total", "selection", "list", "plot", "style")):
            self.table.setHorizontalHeaderItem(i, QTableWidgetItem(label))
        self.table.horizontalHeader().setSectionHidden(self.ColApply, True)
        # setup columns for editable grouping attributes
        for i, attr in self.AttrByCol.items():
            self.table.setHorizontalHeaderItem(
                i, QTableWidgetItem(PlotStyles.StyleAttributeLabels[attr]))
            self.table.horizontalHeader().setSectionHidden(i, True)
        self.table.verticalHeader().hide()
        # other internal init
        self._attrs_shown = False
        self._togglePlotControlsVisibility()
        self.model = None
        self._setting_model = False
        self._currier = PersistentCurrier()
        # row of 'selected' grouping
        self._irow_selgroup = 0

    def clear(self):
        self.table.setRowCount(0)
        self.model = None

    # setup mappings from the group.show_plot attribute to check state
    ShowAttrToCheckState = {
        PlotStyles.ShowNot: Qt.Unchecked,
        PlotStyles.ShowDefault: Qt.PartiallyChecked,
        PlotStyles.ShowAlways: Qt.Checked
    }
    CheckStateToShowAttr = dict([(val, key)
                                 for key, val in ShowAttrToCheckState.items()])

    def _makeCheckItem(self, name, group, attr):
        item = QTableWidgetItem(name)
        if group is self.model.defgroup:
            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
            item.setCheckState(
                Qt.Checked if getattr(group.style, attr) else Qt.Unchecked)
        else:
            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable
                          | Qt.ItemIsTristate)
            item.setCheckState(self.ShowAttrToCheckState[getattr(
                group.style, attr)])
        return item

    def _updateModel(self, what=SkyModel.UpdateAll, origin=None):
        if origin is self or not what & (SkyModel.UpdateTags
                                         | SkyModel.UpdateGroupStyle):
            return
        model = self.model
        self._setting_model = True  # to ignore cellChanged() signals (in valueChanged())
        # _item_cb is a dict (with row,col keys) containing the widgets (CheckBoxes ComboBoxes) per each cell
        self._item_cb = {}
        # lists of "list" and "plot" checkboxes per each grouping (excepting the default grouping); each entry is an (row,col,item) tuple.
        # used as argument to self._showControls()
        self._list_controls = []
        self._plot_controls = []
        # list of selection callbacks (to which signals are connected)
        self._callbacks = []
        # set requisite number of rows,and start filling
        self.table.setRowCount(len(model.groupings))
        for irow, group in enumerate(model.groupings):
            self.table.setItem(irow, 0, QTableWidgetItem(group.name))
            if group is model.selgroup:
                self._irow_selgroup = irow
            # total # source in group: skip for "current"
            if group is not model.curgroup:
                self.table.setItem(irow, 1, QTableWidgetItem(str(group.total)))
            # selection controls: skip for current and selection
            if group not in (model.curgroup, model.selgroup):
                btns = QWidget()
                lo = QHBoxLayout(btns)
                lo.setContentsMargins(0, 0, 0, 0)
                lo.setSpacing(0)
                # make selector buttons (depending on which group we're in)
                if group is model.defgroup:
                    Buttons = (("+", lambda src, grp=group: True,
                                "select all sources"),
                               ("-", lambda src, grp=group: False,
                                "unselect all sources"))
                else:
                    Buttons = (
                        ("=", lambda src, grp=group: grp.func(src),
                         "select only this grouping"),
                        ("+",
                         lambda src, grp=group: src.selected or grp.func(src),
                         "add grouping to selection"),
                        ("-", lambda src, grp=group: src.selected and not grp.
                         func(src), "remove grouping from selection"),
                        ("&&",
                         lambda src, grp=group: src.selected and grp.func(src),
                         "intersect selection with grouping"))
                lo.addStretch(1)
                for label, predicate, tooltip in Buttons:
                    btn = QToolButton(btns)
                    btn.setText(label)
                    btn.setMinimumWidth(24)
                    btn.setMaximumWidth(24)
                    btn.setToolTip(tooltip)
                    lo.addWidget(btn)
                    # add callback
                    btn.clicked.connect(
                        self._currier.curry(self.selectSources, predicate))
                lo.addStretch(1)
                self.table.setCellWidget(irow, 2, btns)
            # "list" checkbox (not for current and selected groupings: these are always listed)
            if group not in (model.curgroup, model.selgroup):
                item = self._makeCheckItem("", group, "show_list")
                self.table.setItem(irow, self.ColList, item)
                item.setToolTip(
                    """<P>If checked, sources in this grouping will be listed in the source table. If un-checked, sources will be
            excluded from the table. If partially checked, then the default list/no list setting of "all sources" will be in effect.
            </P>""")
            # "plot" checkbox (not for the current grouping, since that's always plotted)
            if group is not model.curgroup:
                item = self._makeCheckItem("", group, "show_plot")
                self.table.setItem(irow, self.ColPlot, item)
                item.setToolTip(
                    """<P>If checked, sources in this grouping will be included in the plot. If un-checked, sources will be
            excluded from the plot. If partially checked, then the default plot/no plot setting of "all sources" will be in effect.
            </P>""")
            # custom style control
            # for default, current and selected, this is just a text label
            if group is model.defgroup:
                item = QTableWidgetItem("default:")
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setToolTip(
                    """<P>This is the default plot style used for all sources for which a custom grouping style is not selected.</P>"""
                )
                self.table.setItem(irow, self.ColApply, item)
            elif group is model.curgroup:
                item = QTableWidgetItem("")
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setToolTip(
                    """<P>This is the plot style used for the highlighted source, if any.</P>"""
                )
                self.table.setItem(irow, self.ColApply, item)
            elif group is model.selgroup:
                item = QTableWidgetItem("")
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setToolTip(
                    """<P>This is the plot style used for the currently selected sources.</P>"""
                )
                self.table.setItem(irow, self.ColApply, item)
            # for the rest, a combobox with custom priorities
            else:
                cb = QComboBox()
                cb.addItems(["default"] +
                            ["custom %d" % p for p in range(1, 10)])
                index = max(0, min(group.style.apply, 9))
                #        dprint(0,group.name,"apply",index)
                cb.setCurrentIndex(index)
                cb.activated[int].connect(
                    self._currier.xcurry(self._valueChanged,
                                         (irow, self.ColApply)))
                self.table.setCellWidget(irow, self.ColApply, cb)
                cb.setToolTip(
                    """<P>This controls whether sources within this group are plotted with a customized
            plot style. Customized styles have numeric priority; if a source belongs to multiple groups, then
            the style with the lowest priority takes precedence.<P>""")
            # attribute comboboxes
            for icol, attr in self.AttrByCol.items():
                # get list of options for this style attribute. If dealing with first grouping (i==0), which is
                # the "all sources" grouping, then remove the "default" option (which is always first in the list)
                options = PlotStyles.StyleAttributeOptions[attr]
                if irow == 0:
                    options = options[1:]
                # make combobox
                cb = QComboBox()
                cb.addItems(list(map(str, options)))
                # the "label" option is also editable
                if attr == "label":
                    cb.setEditable(True)
                try:
                    index = options.index(getattr(group.style, attr))
                    cb.setCurrentIndex(index)
                except ValueError:
                    cb.setEditText(str(getattr(group.style, attr)))
                slot = self._currier.xcurry(self._valueChanged, (irow, icol))
                cb.activated[int].connect(slot)
                cb.editTextChanged['QString'].connect(slot)
                cb.setEnabled(group is model.defgroup or group.style.apply)
                self.table.setCellWidget(irow, icol, cb)
                label = attr
                if irow:
                    cb.setToolTip(
                        """<P>This is the %s used to plot sources in this group, when a "custom" style for the group
          is enabled via the style control.<P>""" % label)
                else:
                    cb.setToolTip(
                        "<P>This is the default %s used for all sources for which a custom style is not specified below.<P>"
                        % label)
        self.table.resizeColumnsToContents()
        # re-enable processing of cellChanged() signals
        self._setting_model = False

    def setModel(self, model):
        self.model = model
        self.model.connect("updated", self._updateModel)
        self.model.connect("selected", self.updateModelSelection)
        self._updateModel(SkyModel.UpdateAll)

    def _valueChanged(self, row, col):
        """Called when a cell has been edited"""
        if self._setting_model:
            return
        group = self.model.groupings[row]
        item = self.table.item(row, col)
        if col == self.ColList:
            if group is not self.model.defgroup:
                # tri-state items go from unchecked to checked when user clicks them. Make them partially checked instead.
                if group.style.show_list == PlotStyles.ShowNot and item.checkState(
                ) == Qt.Checked:
                    item.setCheckState(Qt.PartiallyChecked)
            group.style.show_list = self.CheckStateToShowAttr[
                item.checkState()]
            self.model.emitChangeGroupingVisibility(group, origin=self)
            return
        elif col == self.ColPlot:
            if group is not self.model.defgroup:
                # tri-state items go from unchecked to checked by default. Make them partially checked instead.
                if group.style.show_plot == PlotStyles.ShowNot and item.checkState(
                ) == Qt.Checked:
                    item.setCheckState(Qt.PartiallyChecked)
            group.style.show_plot = self.CheckStateToShowAttr[
                item.checkState()]
        elif col == self.ColApply:
            group.style.apply = self.table.cellWidget(row, col).currentIndex()
            # enable/disable editable cells
            for j in list(self.AttrByCol.keys()):
                item1 = self.table.item(row, j)
                if item1:
                    fl = item1.flags() & ~Qt.ItemIsEnabled
                    if group.style.apply:
                        fl |= Qt.ItemIsEnabled
                    item1.setFlags(fl)
                cw = self.table.cellWidget(row, j)
                cw and cw.setEnabled(group.style.apply)
        elif col in self.AttrByCol:
            cb = self.table.cellWidget(row, col)
            txt = str(cb.currentText())
            attr = self.AttrByCol[col]
            if txt == "default":
                setattr(group.style, attr, PlotStyles.DefaultValue)
            else:
                setattr(group.style, attr,
                        PlotStyles.StyleAttributeTypes.get(attr, str)(txt))
        # all other columns: return so we don't emit a signal
        else:
            return
        # in all cases emit a signal
        self.model.emitChangeGroupingStyle(group, origin=self)

    def selectSources(self, predicate, curry=False):
        """Selects sources according to predicate(src)"""
        busy = BusyIndicator()
        for src in self.model.sources:
            src.selected = predicate(src)
        self.model.emitSelection(origin=self)
        busy.reset_cursor()

    def updateModelSelection(self, nsel, origin=None):
        """This is called when some other widget changes the set of selected model sources"""
        self.table.clearSelection()
        if self.model:
            self.table.item(self._irow_selgroup, 1).setText(str(nsel))

    def _togglePlotControlsVisibility(self):
        if self._attrs_shown:
            self._attrs_shown = False
            self.table.hideColumn(self.ColApply)
            for col in self.AttrByCol.keys():
                self.table.hideColumn(col)
            self._showattrbtn.setText("Show plot styles >>")
        else:
            self._attrs_shown = True
            self.table.showColumn(self.ColApply)
            for col in self.AttrByCol.keys():
                self.table.showColumn(col)
            self._showattrbtn.setText("<< Hide plot styles")
Beispiel #3
0
class Ui(QApplication):
    def __init__(self):
        super().__init__(argv)
        self.w = QMainWindow()
        self.w.setMinimumWidth(300)
        self.w.setMinimumHeight(300)
        # self.w.setWindowTitle(tr("Отправка запросов на ВС АУГО"))
        self.cw = QScrollArea()
        # self.__create_ui()
        self.__showed = False
        self.__wgts = {}
        self.cb = QComboBox()
        self.individuals = []
        self.entities = []
        self.documents = []
        self.doc_files = []
        self.__setupUi(self.w)
        self.w.showMaximized()

    def report_error(self, msg=None):
        if not msg:
            etype, value, tb = exc_info()
            trace = ''.join(format_exception(etype, value, tb))
            delim_len = 40
            msg = ("*" * delim_len + "\n%s\n" + "*" * delim_len) % trace
            error(msg)
        mb = QMessageBox(QMessageBox.Critical, tr('Ошибка'),
                         str(exc_info()[1]))
        mb.setDetailedText(msg)
        mb.exec()

    def __create_ui(self):
        self.l = QGridLayout()
        self.t = QTableWidget(0, 3)
        self.t.setHorizontalHeaderLabels(
            ('№ дела (обращения)', 'Дата приёма', 'Дата отправки в СМЭВ'))
        self.t.resizeColumnsToContents()
        self.l.addWidget(self.t, 0, 0, 1, 2)
        w = QWidget()
        hl = QHBoxLayout(w)
        hl.setDirection(QHBoxLayout.LeftToRight)
        hl.addWidget(QWidget())
        ok_b = QPushButton(tr('Добавить запрос'))
        ok_b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
        ok_b.clicked.connect(self.__show_form)
        hl.addWidget(ok_b)
        w.setLayout(hl)
        self.l.addWidget(w, 1, 0, 1, 2)
        w = QWidget()
        w.setLayout(self.l)
        self.cw.setWidget(w)
        # self.cw.setLayout(self.l)
        # self.w.setCentralWidget(self.cw)
        w = QWidget()
        l = QVBoxLayout()
        l.addWidget(self.cw)
        w.setLayout(l)
        self.w.setCentralWidget(w)

    def __setupUi(self, mainWindow):
        mainWindow.setObjectName("MainWindow")
        self.centralwidget = QWidget(mainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout = QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.scrollArea = QScrollArea(self.centralwidget)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QWidget()
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents)
        self.gridLayout.setObjectName("gridLayout")
        self.__show_form()
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.horizontalLayout.addWidget(self.scrollArea)
        mainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(mainWindow)
        self.menubar.setObjectName("menubar")
        self.menu = QMenu(self.menubar)
        self.menu.setObjectName("menu")
        mainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(mainWindow)
        self.statusbar.setObjectName("statusbar")
        mainWindow.setStatusBar(self.statusbar)
        self.action_1 = QAction(mainWindow)
        self.action_1.setObjectName("action")
        self.action_1.triggered.connect(self.send)
        self.action = QAction(mainWindow)
        self.action.setObjectName("action")
        self.action.triggered.connect(self.on_action_triggered)
        self.action_2 = QAction(mainWindow)
        self.action_2.setObjectName("action_2")
        self.action_3 = QAction(mainWindow)
        self.action_3.setObjectName("action_3")
        self.action_3.triggered.connect(self.get_response)
        self.menu.addAction(self.action)
        self.menubar.addAction(self.action_1)
        self.menubar.addAction(self.action_2)
        self.menubar.addAction(self.action_3)
        self.menubar.addAction(self.menu.menuAction())

        self.__retranslateUi(mainWindow)
        QMetaObject.connectSlotsByName(mainWindow)

    @pyqtSlot(bool)
    def get_response(self):
        try:
            from dmsic import Integration
            i = Integration(self)
            res = i.get_response()[0]
            if res:
                QMessageBox.information(self.w, tr("Получен ответ"), str(res))
        except:
            self.report_error()

    @pyqtSlot(bool)
    def send(self):
        try:
            from dmsic import Integration
            i = Integration(self)
            declar = {}
            for k, v in self.__wgts.items():
                if k in ('object_address', 'AppliedDocument', 'legal_entity',
                         'person'):
                    a = {}
                    for key, val in v.items():
                        if val.metaObject().className() == 'QDateEdit':
                            a[key] = datetime.strptime(val.text(), '%d.%m.%Y')
                        else:
                            a[key] = val.text()
                    declar[k] = a
                else:
                    if v.metaObject().className() == 'QDateEdit':
                        declar[k] = datetime.strptime(v.text(), '%d.%m.%Y')
                    else:
                        declar[k] = v.text()
            a = declar[
                'AppliedDocument'] if 'AppliedDocument' in declar else []
            for v in self.documents:
                d = {}
                for key, val in v.items():
                    if val.metaObject().className() == 'QDateEdit':
                        d[key] = datetime.strptime(val.text(), '%d.%m.%Y')
                    else:
                        d[key] = val.text()
                if not self.doc_files:
                    raise Exception('Добавте файл документа')
                d['file_name'] = self.doc_files[self.documents.index(v)]
                a.append(d)
            declar['AppliedDocument'] = a
            a = declar['person'] if 'person' in declar else []
            for v in self.individuals:
                ind = {}
                for key, val in v.items():
                    if key in ('address', 'fact_address'):
                        adr = {}
                        for k, vl in val.items():
                            adr[k] = vl.text()
                        ind[key] = adr
                    else:
                        if val.metaObject().className() == 'QDateEdit':
                            ind[key] = datetime.strptime(
                                val.text(), '%d.%m.%Y')
                        else:
                            ind[key] = val.text()
                a.append(ind)
            declar['person'] = a
            a = declar['legal_entity'] if 'legal_entity' in declar else []
            for v in self.entities:
                ent = {}
                for key, val in v.items():
                    if key == 'address':
                        adr = {}
                        for k, vl in val.items():
                            adr[k] = vl.text()
                        ent[key] = adr
                    else:
                        if val.metaObject().className() == 'QDateEdit':
                            ent[key] = datetime.strptime(
                                val.text(), '%d.%m.%Y')
                        else:
                            ent[key] = val.text()
                a.append(ent)
            declar['legal_entity'] = a
            i.send(declar)
            mb = QMessageBox(self.w)
            mb.information(self.w, tr('Готово'), tr('Запрос отправлен'))
        except:
            self.report_error()

    @pyqtSlot(bool)
    def on_action_triggered(self):
        a = Ui_Dialog()
        d = QDialog()
        a.setupUi(d)
        d.exec()

    def __retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(
            _translate("MainWindow", "Отправка запросов на ВС АУГО"))
        # self.pushButton.setText(_translate("MainWindow", "Добавить"))
        self.menu.setTitle(_translate("MainWindow", "Справка"))
        self.action_1.setText(_translate("MainWindow", "Отправить"))
        self.action_2.setText(_translate("MainWindow", "Настройка"))
        self.action.setText(_translate("MainWindow", "О программе"))
        self.action_3.setText(_translate("MainWindow", "Получить ответ"))

    @pyqtSlot(bool)
    def __show_form(self):
        if self.__showed:
            return

        self.gridLayout.addWidget(
            QLabel(tr('№ дела (обращения) <em style="color: red">*</em>')))
        w = QLineEdit()
        self.gridLayout.addWidget(w)
        w.setFocus()
        self.__wgts['declar_number'] = w
        self.gridLayout.addWidget(
            QLabel(
                tr('Услуга (код или номер, или наименование)<em style="color: red">*</em>'
                   )))
        w = QLineEdit()
        self.gridLayout.addWidget(w)
        self.__wgts['service'] = w
        self.gridLayout.addWidget(
            QLabel(
                tr('Дата регистрации запроса <em style="color: red">*</em>')))
        de = QDateEdit(QDate().currentDate())
        de.setCalendarPopup(True)
        self.gridLayout.addWidget(de)
        self.__wgts['register_date'] = de
        self.gridLayout.addWidget(
            QLabel(
                tr('Плановый срок предоставления услуги <em style="color: red">*</em>'
                   )))
        de = QDateEdit()
        self.__wgts['register_date'].dateChanged.connect(de.setMinimumDate)
        de.setCalendarPopup(True)
        de.setMinimumDate(self.__wgts['register_date'].date())
        self.gridLayout.addWidget(de)
        self.__wgts['end_date'] = de

        gb = QGroupBox(tr('Место нахождения объекта услуги'))
        gb_l = QGridLayout()
        self.__wgts['object_address'] = self.__add_address(gb_l)
        gb.setLayout(gb_l)
        self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2)

        doc = {}
        gb = QGroupBox(tr('Приложенный документ *'))
        gb_l = QGridLayout()
        gb_l.addWidget(
            QLabel(tr('Наименование документа <em style="color: red">*</em>')))
        w = QLineEdit()
        w.setMaxLength(1024)
        gb_l.addWidget(w, 0, 1, 1, 1)
        doc['title'] = w
        gb_l.addWidget(
            QLabel(tr('Номер документа <em style="color: red">*</em>')))
        w = QLineEdit()
        w.setMaxLength(50)
        gb_l.addWidget(w)
        doc['number'] = w
        gb_l.addWidget(
            QLabel(tr('Дата документа <em style="color: red">*</em>')))
        w = QDateEdit()
        w.setCalendarPopup(True)
        gb_l.addWidget(w)
        doc['date'] = w
        gb_l.addWidget(
            QLabel(
                tr('Прямая ссылка на файл. Поддерживаются только пртоколы '
                   'HTTP, FTP <em style="color: red">*</em>')))
        w = QLineEdit()
        gb_l.addWidget(w)
        doc['url'] = w
        gb.setLayout(gb_l)
        self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2)
        self.documents.append(doc)

        gb = QGroupBox(tr('Заявители *'))
        self.dec_layout = QGridLayout()
        self.cb = QComboBox()
        self.cb.addItems(('Физическое лицо',
                          'Юридическое лицо/Индивидуальный предприниматель'))
        self.dec_layout.addWidget(self.cb)
        b = QPushButton(tr('Добавить'))
        b.clicked.connect(self.add_declarant)
        self.dec_layout.addWidget(b, 0, 1, 1, 1)
        gb.setLayout(self.dec_layout)
        self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2)

        b = QPushButton(tr('Добавить файл документа'))
        b.clicked.connect(self.__add_doc_file)
        self.gridLayout.addWidget(b)
        self.file_label = QLabel()
        self.gridLayout.addWidget(self.file_label)
        self.warn_label = QLabel(tr("Не удаляйте файл до отправки запроса"))
        self.warn_label.setStyleSheet('color: red')
        self.warn_label.setVisible(False)
        self.gridLayout.addWidget(self.warn_label,
                                  self.gridLayout.rowCount() + 1, 0, 1, 2)

        self.__showed = True

    @pyqtSlot(bool)
    def __add_doc_file(self):
        file_name = QFileDialog.getOpenFileName(
            caption=tr('Выбурите файл'),
            filter=tr('Файлы pdf (*.pdf);;Все файлы (*.*)'))[0]
        self.file_label.setText(file_name)
        if self.doc_files:
            self.doc_files = []
        self.doc_files.append(file_name)
        self.warn_label.setVisible(True)

    def __add_address(self, gb_l):
        wgts = {}
        gb_l.addWidget(QLabel(tr('Почтовый индекс')))
        w = QLineEdit()
        gb_l.addWidget(w, 0, 1, 1, 1)
        wgts['Postal_Code'] = w
        gb_l.addWidget(QLabel(tr('Регион')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['Region'] = w
        gb_l.addWidget(QLabel(tr('Район')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['District'] = w
        gb_l.addWidget(QLabel(tr('Муниципальное образование')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['City'] = w
        gb_l.addWidget(QLabel(tr('Городской район')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['Urban_District'] = w
        gb_l.addWidget(QLabel(tr('Сельсовет')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['Soviet_Village'] = w
        gb_l.addWidget(
            QLabel(tr('Населенный пункт <em style="color: red">*</em>')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['Locality'] = w
        cb = QComboBox()
        cb.addItems(('Вариант 1', 'Вариант 2'))
        gb_l.addWidget(cb)
        st = QStackedWidget()
        p1 = QWidget()
        l = QGridLayout()
        l.setSpacing(3)
        l.addWidget(QLabel(tr('Улица <em style="color: red">*</em>')))
        w = QLineEdit()
        l.addWidget(w, 0, 1, 1, 1)
        wgts["Street"] = w
        l.addWidget(QLabel(tr('Дом <em style="color: red">*</em>')))
        w = QLineEdit()
        l.addWidget(w)
        wgts["House"] = w
        p1.setLayout(l)
        st.addWidget(p1)
        p2 = QWidget()
        l = QGridLayout()
        l.setSpacing(3)
        l.addWidget(QLabel(tr('Ориентир')))
        w = QLineEdit()
        l.addWidget(w, 0, 1, 1, 1)
        wgts["Reference_point"] = w
        p2.setLayout(l)
        st.addWidget(p2)
        gb_l.addWidget(st, 9, 0, 1, 2)
        cb.activated.connect(st.setCurrentIndex)
        gb_l.addWidget(QLabel(tr('Корпус')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['Housing'] = w
        gb_l.addWidget(QLabel(tr('Строение')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['Building'] = w
        gb_l.addWidget(QLabel(tr('Квартира')))
        w = QLineEdit()
        gb_l.addWidget(w)
        wgts['Apartment'] = w
        return wgts

    @pyqtSlot(bool)
    def add_declarant(self, var=True, gl=None):
        if not gl:
            gl = self.dec_layout
        dc = {}
        gb_l = QGridLayout()
        if self.cb.currentIndex() == 0 or gl != self.dec_layout:
            # Add Individual
            gb = QGroupBox(tr('Физическое лицо *'))
            gb_l.addWidget(QLabel(tr('Фамилия <em style="color: red">*</em>')))
            w = QLineEdit()
            gb_l.addWidget(w, 0, 1, 1, 1)
            dc['surname'] = w
            gb_l.addWidget(QLabel(tr('Имя <em style="color: red">*</em>')))
            w = QLineEdit()
            gb_l.addWidget(w)
            dc['first_name'] = w
            gb_l.addWidget(QLabel(tr('Отчество')))
            w = QLineEdit()
            gb_l.addWidget(w)
            dc['patronymic'] = w

            adr = QGroupBox(tr('Адрес регистрации *'))
            adr_l = QGridLayout()
            dc['address'] = self.__add_address(adr_l)
            adr.setLayout(adr_l)
            gb_l.addWidget(adr, gb_l.rowCount() + 1, 0, 1, 2)

            gb.setLayout(gb_l)
            gl.addWidget(gb, gl.rowCount() + 1, 0, 1, 2)
            self.individuals.append(dc)
        else:
            # Add LegalEntity
            gb = QGroupBox(
                tr('Юридическое лицо/Индивидуальный предприниматель *'))
            gb_l.addWidget(
                QLabel(
                    tr('Краткое наименование ЮЛ <em style="color: red">*</em>')
                ))
            w = QLineEdit()
            gb_l.addWidget(w, 0, 1, 1, 1)
            dc['name'] = w

            adr = QGroupBox(tr('Юридический адрес *'))
            adr_l = QGridLayout()
            dc['address'] = self.__add_address(adr_l)
            adr.setLayout(adr_l)
            gb_l.addWidget(adr, gb_l.rowCount() + 1, 0, 1, 2)

            gb.setLayout(gb_l)
            gl.addWidget(gb, gl.rowCount() + 1, 0, 1, 2)
            self.entities.append(dc)
Beispiel #4
0
class TableTab(TraceDocks):

    ## The constructor
    #  initialize the super-class, assign a name and first configItems
    def __init__(self,parent):
        super(TableTab, self).__init__(parent,'TableTab')
        self.tabName = 'TableTab'
        self.parent = parent
        self.logger.logEvent('Creating Tab now: '+ self.tabName)
        
        # Set a couple of default-values, in case the configParser does not work
        self.snifferConfig.configAutoClearCheck = 1
        self.snifferConfig.configFilterState = 'Local'
        self.snifferConfig.configFilterList = self.snifferFilter.filteredIdList
        
        # By parsing the config now, we assure that we re-load everything
        # the way we left it
        self.snifferConfig.parseConfigFromFile()
        
        self.lastSearchedText = 'nullthiswillneverbefound'
        self.lastMatch = 'purge'
        self.lastIndex = 0

    ## Create the visible UI
    def setTableTabLayout(self):
        
        # Create Table Tab --------------------###    
        # Create Layouts
        self.Vlayout = QVBoxLayout()
        self.H1layout = QHBoxLayout()
        self.H11layout = QHBoxLayout()
        self.H12layout = QHBoxLayout()
        self.H21layout = QHBoxLayout()
        self.V11layout = QVBoxLayout()
        self.V21layout = QVBoxLayout()
        
        # Create Widgets for H1layout
        # First buttons
        self.clearTableButt = QPushButton('Clear Table')
        self.clearTableButt.clicked.connect(self.clearTable)
        self.autoClearCheck = QCheckBox('Auto Clear')
        self.autoClearCheck.stateChanged.connect(self.checkAutoClearChanged)  
        
        self.searchInputField = QLineEdit()
        self.searchInputField.setPlaceholderText('Enter search term, then click search')
        self.searchButt = QPushButton('Search Table')
        self.searchButt.clicked.connect(lambda: self.searchInTable(self.searchInputField.text(),2))
        self.showSummaryButt = QPushButton('Show Summary')
        self.showSummaryButt.clicked.connect(self.showSummary)
         
        self.filterGroup = QButtonGroup()
        self.localFilterRadio = QRadioButton('Local',self)
        self.globalFilterRadio = QRadioButton('Global', self)
        self.configureFilterButt = QPushButton('Configure Filter')
        self.configureFilterButt.clicked.connect(self.configureFilter)
        self.localFilterRadio.clicked.connect(self.localRadioSelected)
        self.globalFilterRadio.clicked.connect(self.globalRadioSelected)
        
        self.H21layout.addWidget(self.localFilterRadio)
        self.H21layout.addWidget(self.globalFilterRadio)
        self.H21layout.addWidget(self.showSummaryButt)
        self.V21layout.addLayout(self.H21layout)
        self.V21layout.addWidget(self.configureFilterButt)
        
        # Add Widgets to H11layout
        self.H11layout.addWidget(self.clearTableButt)
        self.H11layout.addWidget(self.autoClearCheck)
        
        # Add Widgets to H12layout
        self.H12layout.addWidget(self.searchInputField)
        self.H12layout.addWidget(self.searchButt)
        self.H12layout.addStretch()
        
        self.V11layout.addLayout(self.H11layout)
        self.V11layout.addLayout(self.H12layout)
        
        self.H1layout.addLayout(self.V11layout)
        self.H1layout.addLayout(self.V21layout)
        
        self.syncUiToConfig()
        #------------------------------------
        
        # Create Table
        self.detailTableIndex = 0
        self.detailTable = QTableWidget()
        self.detailTableItem = QTableWidgetItem()
        self.detailTable.setRowCount(0)
        self.detailTable.setColumnCount(6)
        
        self.detailTable.setHorizontalHeaderLabels('packID;Tick;Timer;Type;Message;Length'.split(';'))
        self.detailTable.resizeColumnsToContents()
        self.detailTableHeader = self.detailTable.horizontalHeader()
        self.detailTableHeader.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self.detailTableHeader.setSectionResizeMode(1, QHeaderView.ResizeToContents)        
        self.detailTableHeader.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        self.detailTableHeader.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        self.detailTableHeader.setSectionResizeMode(4, QHeaderView.Stretch)
        self.detailTableHeader.setSectionResizeMode(5, QHeaderView.ResizeToContents)

        #------------------------------------                                      
        self.Vlayout.addLayout(self.H1layout)
        self.Vlayout.addWidget(self.detailTable)
        
        self.dockContents.setLayout(self.Vlayout) 
        
         
    ## Fill the main table with the entries from the given list
    #  @param fillTableList the list which is to be parsed into the table        
    def fillTable(self,fillTableList):
        print('Filling Table with all items in PayloadList')
        self.detailTable.scrollToTop() # Scrolls to the top of the table
        self.configAutoClearCheck = True
        if self.configAutoClearCheck == True:
                self.detailTable.setRowCount(0)
                self.detailTableIndex = 0
        Globals.dockDict['dockStart'].progressShotBar.setMaximum(len(Globals.payloadList))
        for self.tablePayload in fillTableList:
            self.detailTable.insertRow(self.detailTableIndex)
            self.detailTable.setItem(self.detailTableIndex,0,QTableWidgetItem(str(self.tablePayload.payloadHead.packetID)))
            self.detailTable.setItem(self.detailTableIndex,1,QTableWidgetItem(str(self.tablePayload.payloadHead.tickCountHigh << 8 | self.tablePayload.payloadHead.tickCountLow)))
            self.detailTable.setItem(self.detailTableIndex,2,QTableWidgetItem(str(self.tablePayload.payloadHead.timerByteHigh << 8 | self.tablePayload.payloadHead.timerByteLow)))
            self.detailTable.setItem(self.detailTableIndex,3,QTableWidgetItem(Globals.tspDict[self.tablePayload.payloadHead.informationID][0]))
            testPayload = self.tablePayload.toDict()
            
            # This a little messy: We check whether an objectDict is available, and if it is
            # we check for the different DataTypes there might be, since the message section is unified.
            # Basically, we need to handle all the different cases there can be, payload0-payload3 and the actual objectType
            if Globals.objectDict:
                if getDataType(self.tablePayload) == 1:
                    if getObjectType(self.tablePayload) == 5:
                        try:
                            self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+': '+Globals.objectDict['TASK'][str(self.tablePayload.data1)])) 
                        except:
                            self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem('FAILED WITH KEYERROR - see printOutput'))
                            print('KEYERROR DETAILS:')
                            print(testPayload)                                                                                      
                elif getDataType(self.tablePayload) == 2:
                    try:
                        self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+': '+Globals.objectDict[Globals.objectTypeDict[self.tablePayload.data1]][str(self.tablePayload.data2)]))
                    except:
                        self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem('FAILED WITH KEYERROR - see printOutput'))
                        print('KEYERROR DETAILS:')
                        print(testPayload)
            # If the objectDict does not exist, we can just dump the raw information into the message-section -> no lookup will be happening
            # and it is up to the user to interpret the data                                 
            else:
                if getDataType(self.tablePayload) == 1:
                    self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)))
                elif getDataType(self.tablePayload) == 2:
                    self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+';'+str(self.tablePayload.data2)))
                elif getDataType(self.tablePayload) == 3:
                    self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+';'+str(self.tablePayload.data2)+';'+str(self.tablePayload.data3)))  

            self.detailTable.setItem(self.detailTableIndex,5,QTableWidgetItem('payload'+str(getDataType(self.tablePayload))))
            
            self.detailTableIndex+=1
            Globals.dockDict['dockStart'].progressShotBar.setValue(self.detailTableIndex)
        Globals.dockDict['dockStart'].progressShotBar.setValue(len(Globals.payloadList))
        Globals.dockDict['dockStart'].displayStatusMessage('Table filled completely, check the tab')
        self.lastSearchedText = 'thisisAWorkAround' # No idea why this is there...

    # --- DOCK-SPECIFIC UI FUNCTIONS --- #
    # -----------------------------------#  
      
    ## Disable all UI-buttons belonging to the tab. This is implementation specific                    
    def disableButtons(self):
        self.clearTableButt.setEnabled(False)
        self.autoClearCheck.setEnabled(False)
        print('Disable TabTable Buttons')
        
    ## CB: clearTableButton // Clear the main table        
    def clearTable(self):
        self.logger.logEvent('clear Table clicked')          
        self.detailTable.setRowCount(0)
        self.detailTableIndex = 0
           
    ## CB: autoClearCheckbox // set the configAutoClearCheck state according to the checkbox   
    def checkAutoClearChanged(self):
        self.snifferConfig.configAutoClearCheck ^= 1          
        self.logger.logEvent('changed Auto Clear Checkbox to - '+ str(self.snifferConfig.configAutoClearCheck))  
        
    ## CB: localRadioButt // set the configFilterState to 'Local'    
    def localRadioSelected(self):
        self.snifferConfig.configFilterState = 'Local'
        self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState))
        
    ## CB: globalRadioButt // set the configFilterState to 'Global'    
    def globalRadioSelected(self):
        self.snifferConfig.configFilterState = 'Global'
        self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState))
            
    ## CB: Show Stats // opens the Stat-Dialog to show misc. information about the measurement           
    def showSummary(self):
        self.snifferStats.show()
        self.snifferStats.showStats()  
        
    ## Searches the table for a string and scrolls to the found item.
    #  @param textToSearch the string that needs to be found in the table
    #  @param column the column where the search needs to take place   
    def searchInTable(self, textToSearch, column):
        if textToSearch not in Globals.IDList:
            QMessageBox.about(self,'Not Found','SearchText not Found!')
            return   

        
        if self.lastSearchedText == textToSearch:
            self.detailTable.setCurrentItem(self.lastFound[self.lastIndex])
            self.detailTable.scrollToItem(self.lastFound[self.lastIndex]) 
            self.lastIndex = self.lastIndex + 1
            if self.lastIndex == len(self.lastFound):
                self.lastIndex = 0
        else:
            foundItems = self.detailTable.findItems(textToSearch, Qt.MatchExactly)
            self.lastSearchedText = textToSearch
            if len(foundItems) != 0:
                self.lastFound = foundItems
                self.lastIndex = 1
                self.detailTable.setCurrentItem(foundItems[0])
                self.detailTable.scrollToItem(self.lastFound[self.lastIndex])


    # --- MANDATORY UI FUNCTIONS --- #
    # -------------------------------# 
             
    ## Read out all components of snifferConfig and set the UI elements according to
    #  the saved values.        
    def syncUiToConfig(self):
        self.autoClearCheck.setChecked(self.snifferConfig.configAutoClearCheck)
        if self.snifferConfig.configFilterState == 'Local':
            self.localFilterRadio.click()
        elif self.snifferConfig.configFilterState == 'Global':
            self.globalFilterRadio.click()
        else:
            print('Error, neither local nor global in config')

    ## Open the correct filter based on the radioButton. If the Global-filter is checked
    #  we assign its calledby variable in order to execute the right callback after the filter is saved.    
    def configureFilter(self):
        if self.localFilterRadio.isChecked():
            self.snifferFilter.show()
        elif self.globalFilterRadio.isChecked():
            Globals.globalFilter.show()
            Globals.globalFilter.calledBy = 'dockTable'
        else:
            print('neither radios checked. Error!')
                                 
    ## CB: // Updates the UI-contents with after filtering has taken place.
    #  This function should not be called by the tab itself, but by the filter
    #  @param filteredIDs the IDs that are to be kept in the payloadList (obsolete)
    #  @param filteredPayloads the new payloadList, which only contains the payloads filtered by the SnifferFilter                   
    def filterUpdated(self, filteredIDs, filteredPayloads):
        print('we arrive from SnifferFilter')
        self.clearTable()
        self.fillTable(filteredPayloads)
class SnifferFilter(QDialog):

    ## The constructor.
    #  Initialize lists to be filled with filtered payloads and
    #  create the dialog.
    def __init__(self, parent):
        super(SnifferFilter, self).__init__()
        self.parent = parent
        self.setWindowTitle('SnifferFilter')
        self.filteredPayloadList = []
        self.filteredIdList = []
        self.layoutingComplete = False

        self.calledBy = 'NONE'  # We store here which tab the filter belongs to, if there is no parent.(Like when the filter is global!)

        self.objectTabDict = {}
        self.filteredObjectDict = {}

        self.resize(670, 700)

    ## Filters the global payloadList by ID by iterating through it and
    #  appending to a new list by filter-criteria
    #  @param filterList a list of IDs that are to be transferred to the new list
    def filterPayloadsByID(self, filterList):
        for payload in Globals.payloadList:
            if hasattr(payload, 'payloadHead'):
                if Globals.tspDict[
                        payload.payloadHead.informationID][0] in filterList:
                    self.filteredPayloadList.append(payload)
                else:
                    #print('informationID is in filteredIdList, skipping packet')
                    pass

    ## Filters the global payloadList by Message by iterating through it and
    #  appending to a new list by filter-criteria
    #  @param filterDict a dictionary of Key: ObjectType and Value: ObjectsToKeep as a template
    #  of which items are to be kept in the filteredList
    def filterPayloadsByMessage(self, filterDict):
        localFilteredList = []
        for payload in self.filteredPayloadList:
            print('payloadID:' + str(payload.payloadHead.informationID))
            # If the ID has nothing to do with the object, we can safely add it.
            if payload.payloadHead.informationID is 23:
                x = 0
                pass
            if isRelatedToObject(payload):
                for objType, messageID in filterDict.items():
                    print(Globals.objectTypeDict[getObjectType(payload)])
                    if Globals.objectTypeDict[getObjectType(
                            payload
                    )] == objType:  # If the objectType matches the one in the dictionary
                        if objType == 0:
                            x = 0
                            pass
                        if getDataType(payload) == 2:
                            if payload.data2 not in messageID:  # and the message does not match the dictionary
                                print(
                                    'Passing data with msgid: ' +
                                    str(payload.data2)
                                )  # don't append, but print that we skipped this one
                            else:
                                localFilteredList.append(
                                    payload
                                )  # the message does match the dictionary -> we want to keep it, so we add it to the list

                        elif getDataType(payload) == 1:
                            if payload.data1 not in messageID:
                                print('Passing data with msgid: ' +
                                      str(payload.data1))
                            else:
                                localFilteredList.append(payload)
                        else:
                            localFilteredList.append(payload)
                    else:
                        # If the ID has nothing to do with the object, we can safely add it.
                        # Also, is the object is not even in the filterDict, we can add it too (this should not happen, but
                        # it's there for safety purposes
                        if getDataType(payload) == 0 or Globals.objectTypeDict[
                                getObjectType(payload)] not in filterDict:
                            localFilteredList.append(payload)
            else:
                localFilteredList.append(payload)

        # In every other case, append it to the list, since we only want to filter out specific objects
        self.filteredPayloadList = list(localFilteredList)

    ## Create the visible UI
    #  like the different tables, the searchbar etc.
    def setSnifferFilterUi(self):

        self.filterTabs = QTabWidget()
        self.H1layout = QHBoxLayout()
        self.Vlayout = QVBoxLayout()

        self.searchInputField = QLineEdit()
        self.searchInputField.setPlaceholderText(
            'Enter search term, then click search')
        self.searchButt = QPushButton('Search Table')
        self.saveFilterButt = QPushButton('Save Filter')
        self.filterTable = QTableWidget()

        self.saveFilterButt.clicked.connect(self.saveFilterList)
        self.searchButt.clicked.connect(
            lambda: self.searchInTable(self.searchInputField.text(), 0))

        # Create Table
        self.filterTableIndex = 0
        self.filterTable = QTableWidget()
        self.filterTableItem = QTableWidgetItem()
        self.filterTable.setRowCount(0)
        self.filterTable.setColumnCount(2)

        self.filterTable.setHorizontalHeaderLabels(
            'informationID;Enable'.split(';'))
        self.filterTable.resizeColumnsToContents()
        self.filterTableHeader = self.filterTable.horizontalHeader()
        self.filterTableHeader.setSectionResizeMode(0, QHeaderView.Stretch)
        self.filterTableHeader.setSectionResizeMode(
            1, QHeaderView.ResizeToContents)

        font = self.getFont()

        self.checkBoxAllIds = self.createCheckBox()
        self.filterTable.itemChanged.connect(self.filterAllIDs)
        self.checkBoxAllMessages = self.createCheckBox()

        # -- Add first Row for all -- #
        self.filterTable.insertRow(self.filterTableIndex)
        idFilterItem = QTableWidgetItem('FILTER ALL IDs')
        idFilterItem.setFont(font)
        messageFilterItem = QTableWidgetItem('FILTER ALL Messages')
        messageFilterItem.setFont(font)
        self.filterTable.setItem(self.filterTableIndex, 0, idFilterItem)
        self.filterTable.setItem(self.filterTableIndex, 1, self.checkBoxAllIds)
        self.filterTableIndex = self.filterTableIndex + 1

        # -- Add informationID filter rows -- #
        for keys, values in Globals.tspDict.items():
            if values[0].startswith('ID'):
                checkBoxFilter = self.createCheckBox()
                self.filterTable.insertRow(self.filterTableIndex)
                self.filterTable.setItem(self.filterTableIndex, 0,
                                         QTableWidgetItem(values[0]))
                self.filterTable.setItem(self.filterTableIndex, 1,
                                         checkBoxFilter)
                self.filterTableIndex = self.filterTableIndex + 1

        self.filterTabs.addTab(self.filterTable, 'Information ID')

        self.H1layout.addWidget(self.searchInputField)
        self.H1layout.addWidget(self.searchButt)
        self.Vlayout.addLayout(self.H1layout)
        self.Vlayout.addWidget(self.filterTabs)
        self.Vlayout.addWidget(self.saveFilterButt)
        #------------------------------------
        self.setLayout(self.Vlayout)
        self.layoutingComplete = True

    ## Updates the visible filter UI to the new objectList
    #  This function is called, when either a new measurement was executed or an old measurement was loaded.
    #  Since the objects shown in the Filter need to be updated.
    def updateObjectFilter(self):
        # -- Add message filter rows -- #
        font = self.getFont()
        self.filterTabs.clear()
        self.filterTabs.addTab(self.filterTable, 'Information ID')
        # For each object in objectList, create a new Table and add it to the tabs.
        for keys, values in Globals.objectDict.items():
            objectFilterTable = QTableWidget()
            objectFilterTable.setRowCount(0)
            objectFilterTable.setColumnCount(2)
            strSplit = keys + ';Enable'
            objectFilterTable.setHorizontalHeaderLabels(strSplit.split(';'))
            objectFilterTable.resizeColumnsToContents()
            filterTableHeader = objectFilterTable.horizontalHeader()
            filterTableHeader.setSectionResizeMode(0, QHeaderView.Stretch)
            filterTableHeader.setSectionResizeMode(
                1, QHeaderView.ResizeToContents)
            checkBoxFilter = self.createCheckBox()

            objectFilterTable.itemChanged.connect(
                lambda *a, table=objectFilterTable: self.filterAllObjectIDs(
                    *a, table=table))

            objectTableIndex = 0
            objectFilterTable.insertRow(objectTableIndex)
            objCat = QTableWidgetItem('FILTER ALL')
            objCat.setFont(font)
            objectFilterTable.setItem(objectTableIndex, 0, objCat)
            objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter)
            objectTableIndex = objectTableIndex + 1
            for keys2, values2 in values.items():
                objectFilterTable.insertRow(objectTableIndex)
                checkBoxFilter = self.createCheckBox()
                objectFilterTable.setItem(
                    objectTableIndex, 0,
                    QTableWidgetItem('ID: ' + str(keys2) + ' Name: ' +
                                     str(values2)))
                objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter)
                objectTableIndex = objectTableIndex + 1

            # Add the newly create table to the tabs.
            self.filterTabs.addTab(objectFilterTable, keys)
            self.objectTabDict[keys] = objectFilterTable

    ## Searches the table for a string and scrolls to the found item.
    #  @param textToSearch the string that needs to be found in the table
    #  @param column the column where the search needs to take place
    def searchInTable(self, textToSearch, column):
        # Create a model of the table, so we can match a text
        tableModel = self.filterTable.model()
        start = tableModel.index(0, column)
        matches = tableModel.match(start, Qt.DisplayRole, textToSearch, 1,
                                   Qt.MatchContains)
        # If there are multiple matches, we take the first one, select it and scroll to it
        if matches:
            index = matches[0]
            self.filterTable.selectionModel().select(
                index, QItemSelectionModel.Select)
            self.filterTable.scrollToItem(
                self.filterTable.itemFromIndex(index))

    ## CB: SaveFilterButton // Call the filterFunctions -> Filter the unfiltered list by ID and Object and call the update
    #  function of the executing tab in order to update their UI.
    def saveFilterList(self):
        self.filteredPayloadList.clear()

        #--Save by ID--#
        rowCnt = self.filterTable.rowCount()
        self.filteredIdList.clear()
        for rows in range(0, rowCnt):
            if self.filterTable.item(rows, 1).checkState() == Qt.Checked:
                #print(self.filterTable.item(rows,0).text())
                self.filteredIdList.append(
                    self.filterTable.item(rows, 0).text())
        self.filterPayloadsByID(self.filteredIdList)
        print(len(self.filteredPayloadList))
        print(len(Globals.payloadList))

        #--Save By Objects--#
        self.filteredObjectDict.clear()
        for objType, objectTable in self.objectTabDict.items():
            rowCnt = objectTable.rowCount()
            objectsToFilter = []
            for rows in range(0, rowCnt):
                if objectTable.item(rows, 1).checkState() == Qt.Checked:
                    #print(objectTable.item(rows,0).text())
                    try:
                        objectsToFilter.append(
                            int(
                                re.search('ID: (.*) Name:.*',
                                          objectTable.item(
                                              rows, 0).text()).group(1)))
                        self.filteredObjectDict[objType] = objectsToFilter
                        #print('Found Regex: '+re.search('ID: (.*) Name:.*',objectTable.item(rows,0).text()).group(1))
                    except:
                        print('Error when parsing TableRegex...this is okay')
        self.filterPayloadsByMessage(self.filteredObjectDict)

        # We filtered the list, now we hide the windows and call the update-function
        # If the maintainer of the tab did not follow the implementation guide, there is no update-function to call.
        # We still save the filtered list, so we print a message to show where to find it.
        self.hide()
        try:
            self.parent.filterUpdated(self.filteredIdList,
                                      self.filteredPayloadList)
        except AttributeError:
            print(
                'No corresponding callable function filterUpdated was found, you can access the most recent filteredList via self.snifferFilter.filteredIdList'
            )
        try:
            Globals.dockDict[self.calledBy].filterUpdated(
                self.filteredIdList, self.filteredPayloadList)
        except:
            print('not global!')

    ## Check whether the first checkbox was checked and then update the entire ID table to either checked or unchecked state
    #  @param checkBox a checkBox we perform the query on
    def filterAllIDs(self, checkBox):
        if self.layoutingComplete == True:
            if checkBox.column() == 1 and checkBox.row(
            ) == 0:  # We clicked the toggle ID checkbox
                if checkBox.checkState() == Qt.Checked:
                    rowCnt = self.filterTable.rowCount()
                    for rows in range(0, rowCnt):
                        try:
                            self.filterTable.item(rows,
                                                  1).setCheckState(Qt.Checked)
                        except AttributeError:
                            print(
                                'no items after' + str(rows) +
                                'found...Maybe this column has less items than'
                                + str(rowCnt) + '?')
                elif checkBox.checkState() == Qt.Unchecked:
                    rowCnt = self.filterTable.rowCount()
                    for rows in range(0, rowCnt):
                        try:
                            self.filterTable.item(rows, 1).setCheckState(
                                Qt.Unchecked)
                        except AttributeError:
                            print(
                                'no items after' + str(rows) +
                                'found...Maybe this column has less items than'
                                + str(rowCnt) + '?')
                else:
                    print(
                        'neither checked nor unchecked...should never be here..'
                    )

    ## Check whether the first checkbox was checked and then update the entire ObjectIDtable to either checked or unchecked state
    #  @param checkBox a checkBox we perform the query on
    #  @param table the table that is to be updated
    def filterAllObjectIDs(self, checkBox, table):
        if (self.objectTabDict):
            if checkBox.column() == 1 and checkBox.row(
            ) == 0:  # We clicked the toggle ID checkbox
                if checkBox.checkState() == Qt.Checked:
                    rowCnt = table.rowCount()
                    for rows in range(0, rowCnt):
                        try:
                            table.item(rows, 1).setCheckState(Qt.Checked)
                        except AttributeError:
                            print(
                                'no items after' + str(rows) +
                                'found...Maybe this column has less items than'
                                + str(rowCnt) + '?')
                elif checkBox.checkState() == Qt.Unchecked:
                    rowCnt = table.rowCount()
                    for rows in range(0, rowCnt):
                        try:
                            table.item(rows, 1).setCheckState(Qt.Unchecked)
                        except AttributeError:
                            print(
                                'no items after' + str(rows) +
                                'found...Maybe this column has less items than'
                                + str(rowCnt) + '?')
                else:
                    print(
                        'neither checked nor unchecked...should never be here..'
                    )

    # --- HELPER FUNCTIONS --- #
    ## Create a defined checkbox within a tableWidgetItem to facilitate filling the table
    #  @return the created checkbox
    def createCheckBox(self):
        myCheck = QTableWidgetItem()
        myCheck.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        myCheck.setCheckState(Qt.Checked)
        return myCheck

    ## Create a defined font (bold,underlined) to facilitate filling the table
    #  @return the created font
    def getFont(self):
        font = QFont()
        font.setBold(True)
        font.setUnderline(True)
        return font
class SnifferStats(QDialog):
    
    
    ## The constructor.
    def __init__(self):
        super().__init__()
        print('Stating')
        
        self.iDList = []
        self.packetCount = 0
        self.counter = 0
        self.statsTableIndex = 0
        self.setWindowTitle('SnifferStats')
        self.snifferAPI = SnifferAPI()
        self.contentBox = QLabel()
        self.statsTable = QTableWidget()
        self.tabs = QTabWidget()
        self.tabBasic = QWidget()    
        self.tabAdvanced = QWidget()
        self.layout = QVBoxLayout()
        
        self.tabs.addTab(self.tabBasic,"Basic")
        self.tabs.addTab(self.tabAdvanced,"Advanced")
        self.tabBasic.layout = QVBoxLayout()
        self.tabAdvanced.layout = QVBoxLayout()
               
               
    ## Shows the stats in Label and Table (Basic and Advanced Tab).
    def showStats(self):
        self.clearTableStats()
        self.clearLabelStats()
        #-Advanced Tab
        self.iDList = self.snifferAPI.getAllInfoIDs(Globals.payloadList)
        self.counter = self.snifferAPI.getCountedInfoIDs(self.iDList)
        self.fillStatTable(Globals.payloadList, self.counter, self.statsTable, self.statsTableIndex)
        #-Basic Tab
        self.setBasicCount(self.contentBox, Globals.payloadList)
    
    
    ## Counts identical informationIDs of the list given as the first parameter
    #  and fills the StatTable in SnifferStats.
    #  This function can be further used to modify SnifferStats table.
    #  Note: This function requires access to the tspDict
    #  @param rList payloadList or filteredList
    #  @param counter as counted list
    #  @param statsTable member
    #  @param statsTableIndex variable
    def fillStatTable(self, rList, counter, statsTable, statsTableIndex):
        try: 
            for iD,amount in counter.items():
                statsTable.insertRow(statsTableIndex)
                statsTable.setItem(statsTableIndex, 0, QTableWidgetItem(Globals.tspDict[iD][0]))
                statsTable.setItem(statsTableIndex, 1, QTableWidgetItem(str(iD)))
                statsTable.setItem(statsTableIndex, 2,QTableWidgetItem(str(amount)))
                statsTableIndex = statsTableIndex + 1
            tList = self.snifferAPI.getSizeOfObjects(rList)
            statsTableIndex = 0
            for size in tList:
                statsTable.setItem(statsTableIndex, 3, QTableWidgetItem(str(size)))
                statsTableIndex = statsTableIndex + 1
        except Exception as e:
            print("Exception occurred: "+str(e))        
            
    ## Writes the PacketCount using getAllPayloadCount() to the label
    # specified as parameter
    # @param cLabel content label
    # @param rList payloadList or filteredList
    def setBasicCount(self, cLabel, rList):
        
        try:
            tList = self.snifferAPI.getSizeOfObjects(Globals.payloadList)
        
            myString = ("Total Packet Count (without failed): "+ str(self.snifferAPI.getAllPayloadCountWithoutFailed(Globals.payloadList, Globals.tspDict))+"\n"
            +"\nTotal Packet Count (all): "+ str(self.snifferAPI.getAllPayloadCountWithFailed(Globals.payloadList))+"\n"
            + "\nTotal load size: "+ str(self.snifferAPI.getListSize(Globals.payloadList))+"\n"
            + "\nMinimal packet size: "+str(self.snifferAPI.getMinSizeOfList(Globals.payloadList))+"\n"
            + "\nMaximal packet size: "+str(self.snifferAPI.getMaxSizeOfList(Globals.payloadList))+"\n"
            + "\nInfoID of minimal packet size: "+str(self.snifferAPI.getInfoIdOfMinObj(Globals.payloadList, Globals.tspDict)[0])
            +" ("+str(self.snifferAPI.getInfoIdOfMinObj(Globals.payloadList, Globals.tspDict)[1])+")\n"
            + "\nInfoID of maximal packet size: "+str(self.snifferAPI.getInfoIdOfMaxObj(Globals.payloadList, Globals.tspDict)[0])
            +" ("+str(self.snifferAPI.getInfoIdOfMaxObj(Globals.payloadList, Globals.tspDict)[1])+")\n"
            +"\nOccurrence of ID_MOVED_TASK_TO_READY_STATE: "+str(self.snifferAPI.getInfoIdTickCount(Globals.payloadList, 11))+" ticks \n" #id is here fix, group evaluates which types are most relevant
            +"\nCount of all non task objects : "+str(self.snifferAPI.getCountNonTaskObj(Globals.objectDict))+"\n"
            +"\nCount of task objects : "+str(self.snifferAPI.getCountTaskObj(Globals.objectDict))+"\n"
            +"\nAll objects: "+str(self.snifferAPI.getObjTypesList(Globals.objectDict))+"\n"
            +"\nTime of Measurement : "+str(self.snifferAPI.getMeasurementTimeSingleShot(Globals.payloadList))+" sec\n"
            +"\nAverage data rate : "+str(self.snifferAPI.getDatarate(Globals.payloadList))+" kbit/sec\n")
            cLabel.setText(myString)
        except Exception as e:
            print("Exception occurred: "+str(e))
     
    ## Sets the SnifferUI   
    def setSnifferStatsUi(self):
        self.setAdvancedTab()   
        self.setBasicTab()         
    
    
    ## Sets the Advanced Tab
    def setAdvancedTab(self):
        self.statsTableItem = QTableWidgetItem()
        self.statsTable.setRowCount(0)
        self.statsTable.setColumnCount(4)
        self.statsTable.setHorizontalHeaderLabels('InformationID;NumericID;Occurrence;PacketSize'.split(';'))
        self.statsTable.resizeColumnsToContents()
        self.statsTableHeader = self.statsTable.horizontalHeader()
        self.statsTableHeader.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self.statsTableHeader.setSectionResizeMode(1, QHeaderView.ResizeToContents) 
        self.statsTableHeader.setSectionResizeMode(2, QHeaderView.ResizeToContents) 
        self.statsTableHeader.setSectionResizeMode(3, QHeaderView.ResizeToContents) 
        self.closeButt = QPushButton('Clear')
        self.closeButt.clicked.connect(self.clearTableStats)     
        self.tabAdvanced.layout.addWidget(self.statsTable)
        self.tabAdvanced.layout.addWidget(self.closeButt)
        self.tabAdvanced.setLayout(self.tabAdvanced.layout)
        #------------------------------------
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
        
    
    ## Sets the Basic Tab
    def setBasicTab(self):
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(self.contentBox)
        self.contentBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.scrollArea.setWidgetResizable(True)
        self.closeButt = QPushButton('Clear')
        self.closeButt.clicked.connect(self.clearLabelStats) 
        self.tabBasic.layout.addWidget(self.scrollArea)
        self.tabBasic.layout.addWidget(self.closeButt)
        self.tabBasic.setLayout(self.tabBasic.layout)
        
    ## Clears the SnifferStats by calling an API function
    def clearTableStats(self):       
        self.deleteStats(self.iDList)
    
    
    ## Clears the SnifferStats by calling an API function
    def clearLabelStats(self):
        self.contentBox.clear()

    ## Clears the StatsView and resets according lists
    # @param list2 with all infoIDs (corresponding to second parameter in getAllInfoIDs()
    def deleteStats(self, list2):
        self.statsTable.setRowCount(0)
        self.statsTableIndex = 0
        self.counter = 0
        list2[:] = []