void ResponseTimeDelayDialog::fillTree()
{
    rtd_data_t rtd_data;
    memset (&rtd_data, 0, sizeof(rtd_data));
    rtd_table_dissector_init(rtd_, &rtd_data.stat_table, NULL, NULL);
    rtd_data.user_data = this;

    QByteArray display_filter = displayFilter().toUtf8();
    if (!registerTapListener(get_rtd_tap_listener_name(rtd_),
                          &rtd_data,
                          display_filter.constData(),
                          0,
                          tapReset,
                          get_rtd_packet_func(rtd_),
                          tapDraw)) {
        free_rtd_table(&rtd_data.stat_table, NULL, NULL);
        reject(); // XXX Stay open instead?
        return;
    }

    statsTreeWidget()->setSortingEnabled(false);

    cap_file_.retapPackets();

    tapDraw(&rtd_data);

    statsTreeWidget()->sortItems(col_type_, Qt::AscendingOrder);
    statsTreeWidget()->setSortingEnabled(true);

    removeTapListeners();
    free_rtd_table(&rtd_data.stat_table, NULL, NULL);
}
ResponseTimeDelayDialog::ResponseTimeDelayDialog(QWidget &parent, CaptureFile &cf, register_rtd *rtd, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    rtd_(rtd)
{
    QString subtitle = tr("%1 Response Time Delay Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd))));
    setWindowSubtitle(subtitle);
    loadGeometry(0, 0, "ResponseTimeDelayDialog");

    QStringList header_names = QStringList()
            << tr("Type") << tr("Messages")
            << tr("Min SRT") << tr("Max SRT") << tr("Avg SRT")
            << tr("Min in Frame") << tr("Max in Frame")
            << tr("Open Requests") << tr("Discarded Responses")
            << tr("Repeated Requests") << tr("Repeated Responses");

    statsTreeWidget()->setHeaderLabels(header_names);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == col_type_) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    if (!filter.isEmpty()) {
        setDisplayFilter(filter);
    }
}
void ResponseTimeDelayDialog::fillTree()
{
    rtd_data_t rtd_data;
    memset (&rtd_data, 0, sizeof(rtd_data));
    rtd_table_dissector_init(rtd_, &rtd_data.stat_table, NULL, NULL);
    rtd_data.user_data = this;

    GString *error_string = register_tap_listener(get_rtd_tap_listener_name(rtd_),
                          &rtd_data,
                          displayFilter(),
                          0,
                          tapReset,
                          get_rtd_packet_func(rtd_),
                          tapDraw);
    if (error_string) {
        QMessageBox::critical(this, tr("Failed to attach to tap \"%1\"").arg(get_rtd_tap_listener_name(rtd_)),
                             error_string->str);
        g_string_free(error_string, TRUE);
        free_rtd_table(&rtd_data.stat_table, NULL, NULL);
        reject();
    }

    statsTreeWidget()->setSortingEnabled(false);

    cf_retap_packets(cap_file_.capFile());

    tapDraw(&rtd_data);

    statsTreeWidget()->sortItems(col_type_, Qt::AscendingOrder);
    statsTreeWidget()->setSortingEnabled(true);

    remove_tap_listener(&rtd_data);
    free_rtd_table(&rtd_data.stat_table, NULL, NULL);
}
ServiceResponseTimeDialog::ServiceResponseTimeDialog(QWidget &parent, CaptureFile &cf, register_srt *srt, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    srt_(srt)
{
    QString subtitle = QString("%1 Service Response Time Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt))));
    setWindowSubtitle(subtitle);

    // Add number of columns for this stats_tree
    QStringList header_labels;
    for (int col = 0; col < NUM_SRT_COLUMNS; col++) {
        header_labels.push_back(service_response_time_get_column_name(col));
    }
    statsTreeWidget()->setColumnCount(header_labels.count());
    statsTreeWidget()->setHeaderLabels(header_labels);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == SRT_COLUMN_PROCEDURE) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    QMenu *submenu;
    QAction *insert_action = ctx_menu_.actions().first();

    FilterAction::Action cur_action = FilterAction::ActionApply;
    submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action));
    foreach (FilterAction::ActionType at, FilterAction::actionTypes()) {
        FilterAction *fa = new FilterAction(submenu, cur_action, at);
        submenu->addAction(fa);
        connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered()));
        filter_actions_ << fa;
    }
ServiceResponseTimeDialog::ServiceResponseTimeDialog(QWidget &parent, CaptureFile &cf, register_srt *srt, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    srt_(srt)
{
    QString subtitle = QString("%1 Service Response Time Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt))));
    setWindowSubtitle(subtitle);

    // Add number of columns for this stats_tree
    QStringList header_labels;
    for (int col = 0; col < NUM_SRT_COLUMNS; col++) {
        header_labels.push_back(service_response_time_get_column_name(col));
    }
    statsTreeWidget()->setColumnCount(header_labels.count());
    statsTreeWidget()->setHeaderLabels(header_labels);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == SRT_COLUMN_PROCEDURE) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    addFilterActions();

    if (!filter.isEmpty()) {
        setDisplayFilter(filter);
    }

    connect(statsTreeWidget(), SIGNAL(itemChanged(QTreeWidgetItem*,int)),
            this, SLOT(statsTreeWidgetItemChanged()));
}
QByteArray StatsTreeDialog::getTreeAsString(st_format_type format)
{
    GString *str_tree;

    // produce output in selected format using current sort information
    str_tree = stats_tree_format_as_str(st_, format, statsTreeWidget()->sortColumn(),
                statsTreeWidget()->header()->sortIndicatorOrder()==Qt::DescendingOrder);

    return gstring_free_to_qbytearray(str_tree);
}
Esempio n. 7
0
void StatsTreeDialog::fillTree()
{
    GString *error_string;
    if (!st_cfg_ || file_closed_) return;

    QString display_name = gchar_free_to_qstring(stats_tree_get_displayname(st_cfg_->name));

    // The GTK+ UI appends "Stats Tree" to the window title. If we do the same
    // here we should expand the name completely, e.g. to "Statistics Tree".
    setWindowSubtitle(display_name);

    st_cfg_->pr = &cfg_pr_;
    cfg_pr_.st_dlg = this;

    if (st_) {
        stats_tree_free(st_);
    }
    st_ = stats_tree_new(st_cfg_, NULL, displayFilter());

    // Add number of columns for this stats_tree
    QStringList header_labels;
    for (int count = 0; count<st_->num_columns; count++) {
        header_labels.push_back(stats_tree_get_column_name(count));
    }
    statsTreeWidget()->setColumnCount(header_labels.count());
    statsTreeWidget()->setHeaderLabels(header_labels);
    resize(st_->num_columns*80+80, height());
    statsTreeWidget()->setSortingEnabled(false);

    error_string = register_tap_listener(st_cfg_->tapname,
                          st_,
                          st_->filter,
                          st_cfg_->flags,
                          resetTap,
                          stats_tree_packet,
                          drawTreeItems);
    if (error_string) {
        QMessageBox::critical(this, tr("%1 failed to attach to tap").arg(display_name),
                             error_string->str);
        g_string_free(error_string, TRUE);
        reject();
    }

    cf_retap_packets(cap_file_.capFile());
    drawTreeItems(st_);

    statsTreeWidget()->setSortingEnabled(true);
    remove_tap_listener(st_);

    st_cfg_->pr = NULL;
}
void ResponseTimeDelayDialog::addRtdTable(const _rtd_stat_table *rtd_table)
{
    for (unsigned i = 0; i < rtd_table->num_rtds; i++) {
        const QString type = val_to_qstring(i, get_rtd_value_string(rtd_), "Other (%d)");
        new RtdTimeStatTreeWidgetItem(statsTreeWidget(), type, &rtd_table->time_stats[i]);
    }
}
const QString LteMacStatisticsDialog::filterExpression()
{
    QString filter_expr;
    if (statsTreeWidget()->selectedItems().count() > 0) {
        QTreeWidgetItem *ti = statsTreeWidget()->selectedItems()[0];

        if (ti->type() == mac_whole_ue_row_type_) {
            MacUETreeWidgetItem *mac_ue_ti = static_cast<MacUETreeWidgetItem*>(ti);
            filter_expr = mac_ue_ti->filterExpression();
        } else {
            MacULDLTreeWidgetItem *mac_channels_ti = static_cast<MacULDLTreeWidgetItem*>(ti);
            filter_expr = mac_channels_ti->filterExpression();
        }
    }
    return filter_expr;
}
const QString ServiceResponseTimeDialog::filterExpression()
{
    QString filter_expr;
    if (statsTreeWidget()->selectedItems().count() > 0) {
        QTreeWidgetItem *ti = statsTreeWidget()->selectedItems()[0];
        if (ti->type() == srt_row_type_) {
            SrtTableTreeWidgetItem *srtt_ti = static_cast<SrtTableTreeWidgetItem *>(ti->parent());
            QString field = srtt_ti->filterField();
            QString value = ti->text(SRT_COLUMN_INDEX);
            if (srtt_ti && !field.isEmpty() && !value.isEmpty()) {
                filter_expr = QString("%1==%2").arg(srtt_ti->filterField()).arg(value);
            }
        }
    }
    return filter_expr;
}
Esempio n. 11
0
void StatsTreeDialog::fillTree()
{
    if (!st_cfg_ || file_closed_) return;

    QString display_name = gchar_free_to_qstring(stats_tree_get_displayname(st_cfg_->name));

    // The GTK+ UI appends "Stats Tree" to the window title. If we do the same
    // here we should expand the name completely, e.g. to "Statistics Tree".
    setWindowSubtitle(display_name);

    st_cfg_->pr = &cfg_pr_;
    cfg_pr_.st_dlg = this;

    if (st_) {
        stats_tree_free(st_);
    }
    QString display_filter = displayFilter();
    st_ = stats_tree_new(st_cfg_, NULL, display_filter.toUtf8().constData());

    // Add number of columns for this stats_tree
    QStringList header_labels;
    for (int count = 0; count<st_->num_columns; count++) {
        header_labels.push_back(stats_tree_get_column_name(count));
    }
    statsTreeWidget()->setColumnCount(header_labels.count());
    statsTreeWidget()->setHeaderLabels(header_labels);
    statsTreeWidget()->setSortingEnabled(false);

    if (!registerTapListener(st_cfg_->tapname,
                             st_,
                             st_->filter,
                             st_cfg_->flags,
                             resetTap,
                             stats_tree_packet,
                             drawTreeItems)) {
        reject(); // XXX Stay open instead?
        return;
    }

    cap_file_.retapPackets();
    drawTreeItems(st_);

    statsTreeWidget()->setSortingEnabled(true);
    removeTapListeners();

    st_cfg_->pr = NULL;
}
void ServiceResponseTimeDialog::statsTreeWidgetItemChanged()
{
    QString procedure_title = service_response_time_get_column_name(SRT_COLUMN_PROCEDURE);

    if (statsTreeWidget()->selectedItems().count() > 0) {
        QTreeWidgetItem *ti = statsTreeWidget()->selectedItems()[0];
        SrtTableTreeWidgetItem *srtt_ti = NULL;
        if (ti->type() == srt_row_type_) {
            srtt_ti = static_cast<SrtTableTreeWidgetItem *>(ti->parent());
        } else {
            srtt_ti = static_cast<SrtTableTreeWidgetItem *>(ti);
        }
        if (srtt_ti) {
            procedure_title = srtt_ti->columnTitle();
        }
    }
    statsTreeWidget()->headerItem()->setText(SRT_COLUMN_PROCEDURE, procedure_title);
}
SimpleStatisticsDialog::SimpleStatisticsDialog(QWidget &parent, CaptureFile &cf, struct _new_stat_tap_ui *stu, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    stu_(stu)
{
    setWindowSubtitle(stu_->title);

    QStringList header_labels;
    for (int col = 0; col < (int) stu_->nfields; col++) {
        header_labels << stu_->fields[col].column_name;
    }
    statsTreeWidget()->setHeaderLabels(header_labels);

    for (int col = 0; col < (int) stu_->nfields; col++) {
        if (stu_->fields[col].align == TAP_ALIGN_RIGHT) {
            statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
        }
    }

    setDisplayFilter(filter);
}
Esempio n. 14
0
ResponseTimeDelayDialog::ResponseTimeDelayDialog(QWidget &parent, CaptureFile &cf, register_rtd *rtd, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    rtd_(rtd)
{
    QString subtitle = QString("%1 Response Time Delay Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd))));
    setWindowSubtitle(subtitle);

    statsTreeWidget()->setHeaderLabels(header_names_);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == col_type_) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    setDisplayFilter(filter);

    if (!filter.isEmpty()) {
        setDisplayFilter(filter);
    }
}
void SimpleStatisticsDialog::addMissingRows(struct _new_stat_data_t *stat_data)
{
    // Hierarchy:
    // - tables (GTK+ UI only supports one currently)
    //   - elements (rows?)
    //     - fields (columns?)
    // For multiple table support we might want to add them as subtrees, with
    // the top-level tree item text set to the column labels for that table.

    // Add any missing rows.
    guint table_index = 0;
    new_stat_tap_table* st_table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, table_index);
    for (guint element = statsTreeWidget()->topLevelItemCount(); element < st_table->num_elements; element++) {
        stat_tap_table_item_type* fields = new_stat_tap_get_field_data(st_table, element, 0);
        SimpleStatisticsTreeWidgetItem *ss_ti = new SimpleStatisticsTreeWidgetItem(statsTreeWidget(), st_table->num_fields, fields);
        for (int col = 0; col < (int) stu_->nfields; col++) {
            if (stu_->fields[col].align == TAP_ALIGN_RIGHT) {
                ss_ti->setTextAlignment(col, Qt::AlignRight);
            }
        }
    }
}
void ServiceResponseTimeDialog::fillTree()
{
    srt_data_t srt_data;
    srt_data.srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table*));
    srt_data.user_data = this;

    srt_table_dissector_init(srt_, srt_data.srt_array, NULL, NULL);

    QString display_filter = displayFilter();
    GString *error_string = register_tap_listener(get_srt_tap_listener_name(srt_),
                          &srt_data,
                          display_filter.toUtf8().constData(),
                          0,
                          tapReset,
                          get_srt_packet_func(srt_),
                          tapDraw);
    if (error_string) {
        QMessageBox::critical(this, tr("Failed to attach to tap \"%1\"").arg(get_srt_tap_listener_name(srt_)),
                             error_string->str);
        g_string_free(error_string, TRUE);
        g_array_free(srt_data.srt_array, TRUE);
        srt_data.srt_array = NULL;
        reject(); // XXX Stay open instead?
        return;
    }

    statsTreeWidget()->setSortingEnabled(false);

    cap_file_.retapPackets();

    // We only have one table. Move its tree items up one level.
    if (statsTreeWidget()->invisibleRootItem()->childCount() == 1) {
        statsTreeWidget()->setRootIndex(statsTreeWidget()->model()->index(0, 0));
    }

    tapDraw(&srt_data);

    statsTreeWidget()->sortItems(SRT_COLUMN_PROCEDURE, Qt::AscendingOrder);
    statsTreeWidget()->setSortingEnabled(true);

    remove_tap_listener(&srt_data);
    g_array_free(srt_data.srt_array, TRUE);
}
void LteMacStatisticsDialog::updateHeaderLabels()
{
    if (statsTreeWidget()->selectedItems().count() > 0 && statsTreeWidget()->selectedItems()[0]->type() == mac_whole_ue_row_type_) {
        // Whole-UE labels
        statsTreeWidget()->setHeaderLabels(mac_whole_ue_row_labels);
    } else if (statsTreeWidget()->selectedItems().count() > 0) {
        switch (statsTreeWidget()->selectedItems()[0]->type()) {
            case mac_ulsch_packet_count_row_type:
            case mac_ulsch_byte_count_row_type:
            case mac_dlsch_packet_count_row_type:
            case mac_dlsch_byte_count_row_type:
                statsTreeWidget()->setHeaderLabels(mac_channel_counts_labels);
                break;

            default:
                break;
        }
    }
    else {
        // Nothing selected yet, but set whole-UE labels.
        statsTreeWidget()->setHeaderLabels(mac_whole_ue_row_labels);
    }
}
void ServiceResponseTimeDialog::addSrtTable(const struct _srt_stat_table *srt_table)
{
    new SrtTableTreeWidgetItem(statsTreeWidget(), srt_table);
}
// Constructor.
LteMacStatisticsDialog::LteMacStatisticsDialog(QWidget &parent, CaptureFile &cf, const char *filter) :
    TapParameterDialog(parent, cf, HELP_STATS_LTE_MAC_TRAFFIC_DIALOG),
    commonStatsCurrent_(false)
{
    setWindowSubtitle(tr("LTE Mac Statistics"));
    loadGeometry(parent.width() * 1, parent.height() * 3 / 4, "LTEMacStatisticsDialog");

    clearCommonStats();

    // Create common_stats_grid to appear just above the filter area.
    int statstree_layout_idx = verticalLayout()->indexOf(filterLayout()->widget());
    QGridLayout *common_stats_grid = new QGridLayout();
    // Insert into the vertical layout
    verticalLayout()->insertLayout(statstree_layout_idx, common_stats_grid);
    int one_em = fontMetrics().height();
    common_stats_grid->setColumnMinimumWidth(2, one_em * 2);
    common_stats_grid->setColumnStretch(2, 1);
    common_stats_grid->setColumnMinimumWidth(5, one_em * 2);
    common_stats_grid->setColumnStretch(5, 1);

    // Create statistics label.
    commonStatsLabel_ = new QLabel(this);
    commonStatsLabel_->setObjectName("statisticsLabel");
    commonStatsLabel_->setTextFormat(Qt::RichText);
    commonStatsLabel_->setTextInteractionFlags(Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse);
    common_stats_grid->addWidget(commonStatsLabel_);


    // Create a grid for filtering-related widgetsto also appear in layout.
    int filter_controls_layout_idx = verticalLayout()->indexOf(filterLayout()->widget());
    QGridLayout *filter_controls_grid = new QGridLayout();
    // Insert into the vertical layout
    verticalLayout()->insertLayout(filter_controls_layout_idx, filter_controls_grid);
    filter_controls_grid->setColumnMinimumWidth(2, one_em * 2);
    filter_controls_grid->setColumnStretch(2, 1);
    filter_controls_grid->setColumnMinimumWidth(5, one_em * 2);
    filter_controls_grid->setColumnStretch(5, 1);

    // Add individual controls into the grid
    showSRFilterCheckBox_ = new QCheckBox(tr("Include SR frames in filter"));
    filter_controls_grid->addWidget(showSRFilterCheckBox_);
    showRACHFilterCheckBox_ = new QCheckBox(tr("Include RACH frames in filter"));
    filter_controls_grid->addWidget(showRACHFilterCheckBox_);

    // Will set whole-UE headings originally.
    updateHeaderLabels();

    statsTreeWidget()->setItemDelegateForColumn(col_ul_padding_percent_, new PercentBarDelegate());
    statsTreeWidget()->setItemDelegateForColumn(col_dl_padding_percent_, new PercentBarDelegate());

    statsTreeWidget()->sortByColumn(col_rnti_, Qt::AscendingOrder);

    // Set up column widths.
    // resizeColumnToContents doesn't work well here, so set sizes manually.
    for (int col = 0; col < statsTreeWidget()->columnCount() - 1; col++) {
        switch (col) {
            case col_rnti_:
                statsTreeWidget()->setColumnWidth(col, one_em * 8);
                break;
            case col_ul_frames_:
                statsTreeWidget()->setColumnWidth(col, one_em * 5);
                break;
            case col_ul_bytes_:
                statsTreeWidget()->setColumnWidth(col, one_em * 5);
                break;
            case col_ul_mb_s_:
                statsTreeWidget()->setColumnWidth(col, one_em * 4);
                break;
            case col_ul_padding_percent_:
                statsTreeWidget()->setColumnWidth(col, one_em * 6);
                break;
            case col_ul_retx_:
                statsTreeWidget()->setColumnWidth(col, one_em * 6);
                break;
            case col_dl_frames_:
                statsTreeWidget()->setColumnWidth(col, one_em * 5);
                break;
            case col_dl_bytes_:
                statsTreeWidget()->setColumnWidth(col, one_em * 5);
                break;
            case col_dl_mb_s_:
                statsTreeWidget()->setColumnWidth(col, one_em * 4);
                break;
            case col_dl_padding_percent_:
                statsTreeWidget()->setColumnWidth(col, one_em * 6);
                break;
            case col_dl_crc_failed_:
                statsTreeWidget()->setColumnWidth(col, one_em * 6);
                break;
            case col_dl_retx_:
                statsTreeWidget()->setColumnWidth(col, one_em * 6);
                break;

            default:
                // The rest are numeric
                statsTreeWidget()->setColumnWidth(col, one_em * 4);
                statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
                break;
        }
    }

    addFilterActions();

    if (filter) {
        setDisplayFilter(filter);
    }

    // Set handler for when the tree item changes to set the appropriate labels.
    connect(statsTreeWidget(), SIGNAL(itemSelectionChanged()),
            this, SLOT(updateHeaderLabels()));

    // Set handler for when display filter string is changed.
    connect(this, SIGNAL(updateFilter(QString)),
            this, SLOT(filterUpdated(QString)));
}
MulticastStatisticsDialog::MulticastStatisticsDialog(QWidget &parent, CaptureFile &cf, const char *filter) :
    TapParameterDialog(parent, cf)
{
    setWindowSubtitle(tr("UDP Multicast Streams"));

    // XXX Use recent settings instead
    resize(parent.width() * 4 / 5, parent.height() * 3 / 4);

    tapinfo_ = new mcaststream_tapinfo_t();
    tapinfo_->user_data = this;
    tapinfo_->tap_reset = tapReset;
    tapinfo_->tap_draw = tapDraw;

    QStringList header_names = QStringList()
            << tr("Source Address") << tr("Source Port")
            << tr("Destination Address") << tr("Destination Port")
            << tr("Packets") << tr("Packets/s")
            << tr("Avg BW (bps)") << tr("Max BW (bps)")
            << tr("Max Burst") << tr("Burst Alarms")
            << tr("Max Buffers (B)") << tr("Buffer Alarms");

    statsTreeWidget()->setHeaderLabels(header_names);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == col_src_addr_ || col == col_dst_addr_) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    burst_measurement_interval_le_ = new SyntaxLineEdit(this);
    burst_alarm_threshold_le_ = new SyntaxLineEdit(this);
    buffer_alarm_threshold_le_ = new SyntaxLineEdit(this);
    stream_empty_speed_le_ = new SyntaxLineEdit(this);
    total_empty_speed_le_ = new SyntaxLineEdit(this);

    int filter_layout_idx = verticalLayout()->indexOf(filterLayout()->widget());
    QGridLayout *param_grid = new QGridLayout();
    int one_em = fontMetrics().height();
    verticalLayout()->insertLayout(filter_layout_idx, param_grid);

    // Label | LineEdit | | Label | LineEdit | | Label | LineEdit
    // 0       1         2  3       4         5  6       7
    param_grid->setColumnMinimumWidth(2, one_em * 2);
    param_grid->setColumnStretch(2, 1);
    param_grid->setColumnMinimumWidth(5, one_em * 2);
    param_grid->setColumnStretch(5, 1);
    param_grid->addWidget(new QLabel(tr("Burst measurement interval (ms):")), 0, 0, Qt::AlignRight);
    param_grid->addWidget(burst_measurement_interval_le_, 0, 1);
    param_grid->addWidget(new QLabel(tr("Burst alarm threshold (packets):")), 0, 3, Qt::AlignRight);
    param_grid->addWidget(burst_alarm_threshold_le_, 0, 4);
    param_grid->addWidget(new QLabel(tr("Buffer alarm threshold (B):")), 0, 6, Qt::AlignRight);
    param_grid->addWidget(buffer_alarm_threshold_le_, 0, 7);

    param_grid->addWidget(new QLabel(tr("Stream empty speed (Kb/s:")), 1, 0, Qt::AlignRight);
    param_grid->addWidget(stream_empty_speed_le_, 1, 1);
    param_grid->addWidget(new QLabel(tr("Total empty speed (Kb/s:")), 1, 3, Qt::AlignRight);
    param_grid->addWidget(total_empty_speed_le_, 1, 4);

    burst_measurement_interval_le_->setText(QString::number(mcast_stream_burstint));
    burst_alarm_threshold_le_->setText(QString::number(mcast_stream_trigger));
    buffer_alarm_threshold_le_->setText(QString::number(mcast_stream_bufferalarm));
    stream_empty_speed_le_->setText(QString::number(mcast_stream_emptyspeed));
    total_empty_speed_le_->setText(QString::number(mcast_stream_cumulemptyspeed));

    line_edits_ = QList<QWidget *>()
            << burst_measurement_interval_le_ << burst_alarm_threshold_le_
            << buffer_alarm_threshold_le_ << stream_empty_speed_le_
            << total_empty_speed_le_;

    foreach (QWidget *line_edit, line_edits_) {
        line_edit->setMinimumWidth(one_em * 5);
        connect(line_edit, SIGNAL(textEdited(QString)), this, SLOT(updateWidgets()));
    }