ProtocolHierarchyDialog::ProtocolHierarchyDialog(QWidget &parent, CaptureFile &cf) :
    WiresharkDialog(parent, cf),
    ui(new Ui::ProtocolHierarchyDialog)
{
    ui->setupUi(this);
    loadGeometry(parent.width() * 4 / 5, parent.height() * 4 / 5);
    setWindowSubtitle(tr("Protocol Hierarchy Statistics"));

    ui->hierStatsTreeWidget->setItemDelegateForColumn(pct_packets_col_, &percent_bar_delegate_);
    ui->hierStatsTreeWidget->setItemDelegateForColumn(pct_bytes_col_, &percent_bar_delegate_);
    ph_stats_t *ph_stats = ph_stats_new(cap_file_.capFile());
    if (ph_stats) {
        ui->hierStatsTreeWidget->invisibleRootItem()->setData(0, Qt::UserRole, VariantPointer<ph_stats_t>::asQVariant(ph_stats));
        g_node_children_foreach(ph_stats->stats_tree, G_TRAVERSE_ALL, addTreeNode, ui->hierStatsTreeWidget->invisibleRootItem());
        ph_stats_free(ph_stats);
    }

    ui->hierStatsTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->hierStatsTreeWidget, SIGNAL(customContextMenuRequested(QPoint)),
                SLOT(showProtoHierMenu(QPoint)));

    ui->hierStatsTreeWidget->setSortingEnabled(true);
    ui->hierStatsTreeWidget->expandAll();

    for (int i = 0; i < ui->hierStatsTreeWidget->columnCount(); i++) {
        ui->hierStatsTreeWidget->resizeColumnToContents(i);
    }

    QMenu *submenu;

    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()));
    }
Example #2
0
ph_stats_t*
ph_stats_new(void)
{
    ph_stats_t	*ps;
    frame_data	*frame;
    guint		tot_packets, tot_bytes;
    progdlg_t	*progbar = NULL;
    gboolean	stop_flag;
    int		count;
    float		progbar_val;
    GTimeVal	start_time;
    gchar		status_str[100];
    int		progbar_nextstep;
    int		progbar_quantum;

    /* Initialize the data */
    ps = g_new(ph_stats_t, 1);
    ps->tot_packets = 0;
    ps->tot_bytes = 0;
    ps->stats_tree = g_node_new(NULL);
    ps->first_time = 0.0;
    ps->last_time = 0.0;

    /* Update the progress bar when it gets to this value. */
    progbar_nextstep = 0;
    /* When we reach the value that triggers a progress bar update,
       bump that value by this amount. */
    progbar_quantum = cfile.count/N_PROGBAR_UPDATES;
    /* Count of packets at which we've looked. */
    count = 0;
    /* Progress so far. */
    progbar_val = 0.0f;

    stop_flag = FALSE;
    g_get_current_time(&start_time);

    tot_packets = 0;
    tot_bytes = 0;

    for (frame = cfile.plist_start; frame != NULL; frame = frame->next) {
        /* Create the progress bar if necessary.
           We check on every iteration of the loop, so that
           it takes no longer than the standard time to create
           it (otherwise, for a large file, we might take
           considerably longer than that standard time in order
           to get to the next progress bar step). */
        if (progbar == NULL)
            progbar = delayed_create_progress_dlg(
                          "Computing", "protocol hierarchy statistics",
                          TRUE, &stop_flag, &start_time, progbar_val);

        /* Update the progress bar, but do it only N_PROGBAR_UPDATES
           times; when we update it, we have to run the GTK+ main
           loop to get it to repaint what's pending, and doing so
           may involve an "ioctl()" to see if there's any pending
           input from an X server, and doing that for every packet
           can be costly, especially on a big file. */
        if (count >= progbar_nextstep) {
            /* let's not divide by zero. I should never be started
             * with count == 0, so let's assert that
             */
            g_assert(cfile.count > 0);

            progbar_val = (gfloat) count / cfile.count;

            if (progbar != NULL) {
                g_snprintf(status_str, sizeof(status_str),
                           "%4u of %u frames", count, cfile.count);
                update_progress_dlg(progbar, progbar_val, status_str);
            }

            progbar_nextstep += progbar_quantum;
        }

        if (stop_flag) {
            /* Well, the user decided to abort the statistics.
               computation process  Just stop. */
            break;
        }

        /* Skip frames that are hidden due to the display filter.
           XXX - should the progress bar count only packets that
           passed the display filter?  If so, it should
           probably do so for other loops (see "file.c") that
           look only at those packets. */
        if (frame->flags.passed_dfilter) {

            if (tot_packets == 0) {
                double cur_time = nstime_to_sec(&frame->abs_ts);
                ps->first_time = cur_time;
                ps->last_time = cur_time;
            }

            /* we don't care about colinfo */
            if (!process_frame(frame, NULL, ps)) {
                /*
                 * Give up, and set "stop_flag" so we
                 * just abort rather than popping up
                 * the statistics window.
                 */
                stop_flag = TRUE;
                break;
            }

            tot_packets++;
            tot_bytes += frame->pkt_len;
        }

        count++;
    }

    /* We're done calculating the statistics; destroy the progress bar
           if it was created. */
    if (progbar != NULL)
        destroy_progress_dlg(progbar);

    if (stop_flag) {
        /*
         * We quit in the middle; throw away the statistics
         * and return NULL, so our caller doesn't pop up a
         * window with the incomplete statistics.
         */
        ph_stats_free(ps);
        return NULL;
    }

    ps->tot_packets = tot_packets;
    ps->tot_bytes = tot_bytes;

    return ps;
}