From Thomas ERSFELD (GSOC13) via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8710 QtShark doesn't have a statistics summary window

Add Summary Statistics to qtshark (Statistics => Summary)
Now, use tabs to split summary display (File Capture details, Capture Statistics)

Add also Comment Summary tab (to replace Statistics => Comments Summary)

From me :
Fix order of summary files in Qtshark.pro

svn path=/trunk/; revision=50470
This commit is contained in:
Alexis La Goutte 2013-07-09 18:08:40 +00:00
parent e8fed416a2
commit 43c3cb4884
11 changed files with 1430 additions and 4 deletions

View File

@ -63,6 +63,7 @@ set(QTSHARK_H_SRC
recent_file_status.h
simple_dialog_qt.h
search_frame.h
summary_dialog.h
splash_overlay.h
syntax_line_edit.h
time_shift_dialog.h
@ -120,6 +121,7 @@ set(QTSHARK_CPP_SRC
related_packet_delegate.cpp
simple_dialog_qt.cpp
sparkline_delegate.cpp
summary_dialog.cpp
search_frame.cpp
splash_overlay.cpp
syntax_line_edit.cpp
@ -150,6 +152,7 @@ set(QTSHARK_UI
preferences_dialog.ui
print_dialog.ui
profile_dialog.ui
summary_dialog.ui
search_frame.ui
splash_overlay.ui
time_shift_dialog.ui

View File

@ -135,6 +135,8 @@ search_frame.cpp search_frame.h: ui_search_frame.h
splash_overlay.cpp splash_overlay.h: ui_splash_overlay.h
summary_dialog.cpp summary_dialog.h: ui_summary_dialog.h
time_shift_dialog.cpp time_shift_dialog.h: ui_time_shift_dialog.h
doxygen:

View File

@ -50,6 +50,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_print_dialog.h \
ui_profile_dialog.h \
ui_search_frame.h \
ui_summary_dialog.h \
ui_splash_overlay.h \
ui_time_shift_dialog.h
@ -126,6 +127,7 @@ MOC_HDRS = \
related_packet_delegate.h \
search_frame.h \
simple_dialog_qt.h \
summary_dialog.h \
sparkline_delegate.h \
splash_overlay.h \
syntax_line_edit.h \
@ -156,6 +158,7 @@ UI_FILES = \
print_dialog.ui \
profile_dialog.ui \
search_frame.ui \
summary_dialog.ui \
splash_overlay.ui \
time_shift_dialog.ui
@ -248,6 +251,7 @@ WIRESHARK_QT_SRC = \
search_frame.cpp \
simple_dialog_qt.cpp \
sparkline_delegate.cpp \
summary_dialog.cpp \
splash_overlay.cpp \
syntax_line_edit.cpp \
time_shift_dialog.cpp \

View File

@ -220,6 +220,7 @@ FORMS += \
profile_dialog.ui \
search_frame.ui \
splash_overlay.ui \
summary_dialog.ui \
time_shift_dialog.ui \
@ -262,6 +263,7 @@ HEADERS += $$HEADERS_WS_C \
profile_dialog.h \
search_frame.h \
splash_overlay.h \
summary_dialog.h \
tango_colors.h \
@ -522,6 +524,7 @@ SOURCES += \
simple_dialog_qt.cpp \
sparkline_delegate.cpp \
splash_overlay.cpp \
summary_dialog.cpp \
syntax_line_edit.cpp \
time_shift_dialog.cpp \
wireshark_application.cpp \

View File

@ -107,6 +107,8 @@ MainWindow::MainWindow(QWidget *parent) :
connect(wsApp, SIGNAL(updateRecentItemStatus(const QString &, qint64, bool)), this, SLOT(updateRecentFiles()));
updateRecentFiles();
connect(&summary_dialog_, SIGNAL(captureCommentChanged()), this, SLOT(updateForUnsavedChanges()));
const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
connect(df_edit, SIGNAL(pushFilterSyntaxStatus(QString&)), main_ui_->statusBar, SLOT(pushFilterStatus(QString&)));
connect(df_edit, SIGNAL(popFilterSyntaxStatus()), main_ui_->statusBar, SLOT(popFilterStatus()));
@ -654,6 +656,9 @@ void MainWindow::saveCaptureFile(capture_file *cf, bool stay_closed) {
any packets that no longer have comments. */
if (discard_comments)
packet_list_queue_draw();
cf->unsaved_changes = false; //we just saved so we signal that we have no unsaved changes
updateForUnsavedChanges(); // we update the title bar to remove the *
break;
case CF_WRITE_ERROR:
@ -770,6 +775,9 @@ void MainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_comments,
any packets that no longer have comments. */
if (discard_comments)
packet_list_queue_draw();
cf->unsaved_changes = false; //we just saved so we signal that we have no unsaved changes
updateForUnsavedChanges(); // we update the title bar to remove the *
return;
case CF_WRITE_ERROR:
@ -1182,8 +1190,11 @@ void MainWindow::setTitlebarForCaptureFile()
// XXX - on non-Mac platforms, put in the application
// name?
//
gchar *window_name;
setWindowFilePath(NULL);
setWindowTitle(cf_get_tempfile_source(cap_file_));
window_name = g_strdup_printf("Capturing from %s", cf_get_tempfile_source(cap_file_)); //TODO : Fix Translate
setWindowTitle(window_name);
g_free(window_name);
} else {
//
// For a user file, set the full path; that way,
@ -1217,13 +1228,19 @@ void MainWindow::setTitlebarForCaptureFile()
}
}
void MainWindow::setTitlebarForSelectedTreeRow()
{
setWindowTitle(tr("The Wireshark Network Analyzer"));
}
void MainWindow::setTitlebarForCaptureInProgress()
{
gchar *window_name;
setWindowFilePath(NULL);
if (cap_file_) {
window_name = g_strdup_printf("Capturing from %s ", cf_get_tempfile_source(cap_file_)); //TODO : Fix Translate
window_name = g_strdup_printf("Capturing from %s", cf_get_tempfile_source(cap_file_)); //TODO : Fix Translate
setWindowTitle(window_name);
g_free(window_name);
} else {
@ -1245,6 +1262,7 @@ void MainWindow::setMenusForCaptureFile(bool force_disable)
main_ui_->actionFileClose->setEnabled(false);
main_ui_->actionFileSave->setEnabled(false);
main_ui_->actionFileSaveAs->setEnabled(false);
main_ui_->actionSummary->setEnabled(false);
main_ui_->actionFileExportPackets->setEnabled(false);
main_ui_->menuFileExportPacketDissections->setEnabled(false);
main_ui_->actionFileExportPacketBytes->setEnabled(false);
@ -1257,6 +1275,7 @@ void MainWindow::setMenusForCaptureFile(bool force_disable)
main_ui_->actionFileClose->setEnabled(true);
main_ui_->actionFileSave->setEnabled(cf_can_save(cap_file_));
main_ui_->actionFileSaveAs->setEnabled(cf_can_save_as(cap_file_));
main_ui_->actionSummary->setEnabled(true);
/*
* "Export Specified Packets..." should be available only if
* we can write the file out in at least one format.
@ -1283,6 +1302,8 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) {
main_ui_->menuFileSet->setEnabled(!capture_in_progress);
main_ui_->actionFileQuit->setEnabled(true);
main_ui_->actionSummary->setEnabled(capture_in_progress);
qDebug() << "FIX: packet list heading menu sensitivity";
// set_menu_sensitivity(ui_manager_packet_list_heading, "/PacketListHeadingPopup/SortAscending",
// !capture_in_progress);
@ -1303,6 +1324,7 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) {
void MainWindow::setMenusForCaptureStopping() {
main_ui_->actionFileQuit->setEnabled(false);
main_ui_->actionSummary->setEnabled(false);
#ifdef HAVE_LIBPCAP
main_ui_->actionStartCapture->setChecked(false);
main_ui_->actionStopCapture->setEnabled(false);

View File

@ -54,6 +54,7 @@
#include "progress_bar.h"
#include "file_set_dialog.h"
#include "capture_file_dialog.h"
#include "summary_dialog.h"
class QAction;
@ -101,6 +102,7 @@ private:
ProtoTree *proto_tree_;
QWidget *previous_focus_;
FileSetDialog file_set_dialog_;
SummaryDialog summary_dialog_;
bool capture_stopping_;
// Pipe input
@ -125,6 +127,7 @@ private:
bool testCaptureFileClose(bool from_quit = false, QString& before_what = *new QString());
void captureStop();
void setTitlebarForSelectedTreeRow();
void setTitlebarForCaptureFile();
void setTitlebarForCaptureInProgress();
void setMenusForCaptureFile(bool force_disable = false);
@ -132,7 +135,7 @@ private:
void setMenusForCaptureStopping();
void setForCapturedPackets(bool have_captured_packets);
void setMenusForFileSet(bool enable_list_files);
void updateForUnsavedChanges();
void setForCaptureInProgress(gboolean capture_in_progress = false);
signals:
@ -144,6 +147,7 @@ public slots:
// in main_window_slots.cpp
void openCaptureFile(QString& cf_path = *new QString(), QString &display_filter = *new QString());
void filterPackets(QString& new_filter = *new QString(), bool force = false);
void updateForUnsavedChanges();
#ifdef HAVE_LIBPCAP
void captureCapturePrepared(capture_session *cap_session);
@ -278,6 +282,8 @@ private slots:
void on_goToLineEdit_returnPressed();
void on_actionStartCapture_triggered();
void on_actionStopCapture_triggered();
void on_actionSummary_triggered();
};

View File

@ -13,6 +13,10 @@
<property name="windowTitle">
<string>Wireshark</string>
</property>
<property name="windowIcon">
<iconset resource="../../image/toolbar.qrc">
<normaloff>:/toolbar/main/hi48-app-wireshark.png</normaloff>:/toolbar/main/hi48-app-wireshark.png</iconset>
</property>
<property name="unifiedTitleAndToolBarOnMac">
<bool>true</bool>
</property>
@ -93,7 +97,7 @@
<x>0</x>
<y>0</y>
<width>960</width>
<height>22</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -293,12 +297,29 @@
<addaction name="menuApplyAsFilter"/>
<addaction name="menuPrepareAFilter"/>
</widget>
<widget class="QMenu" name="menuStatistics">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Statistics</string>
</property>
<addaction name="actionSummary"/>
<addaction name="actionProtocol_Hierarchy"/>
</widget>
<widget class="QMenu" name="menuTelephony">
<property name="title">
<string>Telephony</string>
</property>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuView"/>
<addaction name="menuGo"/>
<addaction name="menuCapture"/>
<addaction name="menuAnalyze"/>
<addaction name="menuStatistics"/>
<addaction name="menuTelephony"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
@ -1177,6 +1198,22 @@
<enum>QAction::PreferencesRole</enum>
</property>
</action>
<action name="actionSummary">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Summary</string>
</property>
</action>
<action name="actionProtocol_Hierarchy">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Protocol Hierarchy</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -360,6 +360,9 @@ void MainWindow::captureFileClosed(const capture_file *cf) {
main_ui_->statusBar->popFileStatus();
cap_file_ = NULL;
summary_dialog_.close();
setTitlebarForSelectedTreeRow();
setMenusForSelectedTreeRow();
}
@ -1736,6 +1739,23 @@ void MainWindow::on_actionStopCapture_triggered()
stopCapture();
}
void MainWindow::on_actionSummary_triggered()
{
summary_dialog_.UpdateValues();
if (summary_dialog_.isMinimized() == true)
{
summary_dialog_.showNormal();
}
else
{
summary_dialog_.show();
}
summary_dialog_.raise();
summary_dialog_.activateWindow();
}
/*
* Editor modelines
*

741
ui/qt/summary_dialog.cpp Normal file
View File

@ -0,0 +1,741 @@
/* summary_dialog.cpp
*
* GSoC 2013 - QtShark
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "summary_dialog.h"
#include "ui_summary_dialog.h"
#include "wireshark_application.h"
#include <QtGui>
SummaryDialog::SummaryDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SummaryDialog)
{
ui->setupUi(this);
ui->tbDisplay->horizontalHeader()->setVisible(true);
/* set column widths */
ui->tbInterfaces->setColumnWidth(0, 305);
ui->tbInterfaces->setColumnWidth(1, 110);
ui->tbInterfaces->setColumnWidth(2, 90);
ui->tbInterfaces->horizontalHeader()->setResizeMode(3, QHeaderView::Stretch);
ui->tbInterfaces->setColumnWidth(4, 160);
ui->tbDisplay->setColumnWidth(0, 265);
ui->tbDisplay->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
ui->tbDisplay->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
ui->tbDisplay->horizontalHeader()->setResizeMode(3, QHeaderView::Stretch);
this->setFixedSize(this->size());
}
/*
* Slots
**/
void SummaryDialog::on_bRefresh_clicked()
{
UpdateValues();
}
void SummaryDialog::on_bSaveComments_clicked()
{
if (cfile.filename != NULL)
{
if (wtap_dump_can_write(cfile.linktypes, WTAP_COMMENT_PER_SECTION))
{
gchar *str = g_strdup((gchar*)ui->teCFComments->toPlainText().toStdString().c_str());
cf_update_capture_comment(&cfile, str);
emit captureCommentChanged();
}
}
}
void SummaryDialog::on_bHelpButton_clicked()
{
wsApp->helpTopicAction(HELP_STATS_SUMMARY_DIALOG);
}
void SummaryDialog::on_bCopyComment_clicked()
{
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(SummaryToString());
}
void SummaryDialog::on_tabWidget_currentChanged(int index)
{
// if we are showing the comment summary tab, we update it with new values
if (index == 2)
{
UpdateValues();
ui->pteCommentSummary->clear();
ui->pteCommentSummary->insertPlainText(SummaryToString());
}
}
/**/
QString SummaryDialog::SummaryToString()
{
UpdateValues();
QString summaryStr;
QTextStream out(&summaryStr);
out << tr("Summary created by Wireshark %1\n\n").arg(wireshark_svnversion);
// File Section
out << tr("File: \n");
out << "\t" << tr("Name:\t\t%1\n").arg(summary_.filename);
out << "\t" << tr("Length:\t\t%1 bytes\n").arg(summary_.file_length);
out << "\t" << tr("Format:\t\t%1%2\n")
.arg(wtap_file_type_string(summary_.file_type))
.arg(summary_.iscompressed? tr(" (gzip compressed)") : "");
out << "\t" << tr("Encapsulation:\t\t%1\n").arg(ui->lEncapsulation->text());
out << "\n\n";
// Time Section
out << tr("Time:\n");
if (summary_.packet_count_ts == summary_.packet_count &&
summary_.packet_count >= 1)
{
// start time
out << "\t" << tr("First packet:\t\t%1\n").arg(ui->lFirstPacket->text());
// stop time
out << "\t" << tr("Last packet:\t\t%1\n").arg(ui->lLastPacket->text());
// elapsed seconds (capture duration)
if (summary_.packet_count_ts >= 2) {
out << "\t" << tr("Elapsed:\t\t%1\n").arg(ui->lElapsed->text());
}
}
out << "\n\n";
// Capture Section
out << tr("Capture:\n");
// // capture HW
// if (summary_.shb_hardware){
// out << INDENT << tr("Capture HW: %1\n").arg(ui_->captureHWLabel->text());
// }
// capture OS
if (summary_.shb_os)
{
out << "\t" << tr("OS:\t%1\n").arg(ui->lOS->text());
}
// capture application
if (summary_.shb_user_appl)
{
out << "\t" << tr("Capture application:\t%1\n").arg(ui->lCaptureApp->text());
}
out << "\n";
// capture interfaces info
for (int i = 0; i < ui->tbInterfaces->rowCount(); i++)
{
out << "\t" << ui->tbInterfaces->item(i,0)->text() << "\n";
out << "\t" << "\t" << tr("Dropped packets:\t%1\n")
.arg(ui->tbInterfaces->item(i,1)->text());
out << "\t" << "\t" << tr("Capture filter:\t\t%1\n")
.arg(ui->tbInterfaces->item(i,2)->text());
out << "\t" << "\t" << tr("Link type:\t\t%1\n")
.arg(ui->tbInterfaces->item(i,3)->text());
out << "\t" << "\t" << tr("Packet size limit:\t%1\n")
.arg(ui->tbInterfaces->item(i,4)->text());
}
out << "\n\n";
// Statistics Section
out << tr("Statistics:\n");
for (int i = 0; i < ui->tbDisplay->rowCount(); i++)
{
out << "\t" << tr("%1:\t%2")
.arg(ui->tbDisplay->item(i,0)->text())
.arg(ui->tbDisplay->item(i,1)->text());
out << "\n";
}
out << "\n\n";
//Capture Comments Section - reads from GUI buffer
if(ui->teCFComments->isEnabled()
&& (!ui->teCFComments->toPlainText().isEmpty()))
{
out << tr("Capture File Comments:\n");
out << ui->teCFComments->toPlainText() << endl;
}
return summaryStr;
}
QString SummaryDialog::TimeToString(time_t ti_time)
{
struct tm *ti_tm;
QString str;
ti_tm = localtime(&ti_time);
if (ti_tm == NULL)
{
str = tr("Not representable");
}
else
{
str = str.sprintf("%04d-%02d-%02d %02d:%02d:%02d",
ti_tm->tm_year + 1900,
ti_tm->tm_mon + 1,
ti_tm->tm_mday,
ti_tm->tm_hour,
ti_tm->tm_min,
ti_tm->tm_sec);
}
return str;
}
void SummaryDialog::UpdateValues()
{
QString output;
iface_options iface;
uint i;
double seconds = 0.0;
double disp_seconds = 0.0;
double marked_seconds = 0.0;
memset(&summary_, 0, sizeof(summary_tally));
/* initial computations */
summary_fill_in(&cfile, &summary_);
#ifdef HAVE_LIBPCAP
summary_fill_in_capture(&cfile, &global_capture_opts, &summary_);
#endif
seconds = summary_.stop_time - summary_.start_time;
disp_seconds = summary_.filtered_stop - summary_.filtered_start;
marked_seconds = summary_.marked_stop - summary_.marked_start;
/*
* File groupbox
* */
/* setting the filename */
ui->lFilename->setText(summary_.filename);
/* setting the length of the file */
ui->lLength->setText(QString(tr("%1 bytes (%2 Mbytes)")).arg((ulong)summary_.file_length).arg((float)summary_.file_length/1048576));
/* format */
ui->lFormat->setText(QString("%1%2").arg(wtap_file_type_string(summary_.file_type), summary_.iscompressed? tr(" (gzip compressed)") : ""));
/* encapsulation */
if (summary_.file_encap_type == WTAP_ENCAP_PER_PACKET)
{
for (i = 0; i < summary_.packet_encap_types->len; i++)
{
output = QString(wtap_encap_string(g_array_index(summary_.packet_encap_types, int, i)));
}
}
else
{
output = QString(wtap_encap_string(summary_.file_encap_type));
}
ui->lEncapsulation->setText(output);
/*
* Time groupbox
* */
/* First packet and Last packet */
ui->lFirstPacket->setText(TimeToString((time_t)summary_.start_time));
ui->lLastPacket->setText(TimeToString((time_t)summary_.stop_time));
/*
* We must have at least two time-stamped packets for the elapsed time
* to be valid.
*/
if (summary_.packet_count_ts >= 2)
{
/* elapsed seconds */
uint elapsed_time = (unsigned int)summary_.elapsed_time;
if(elapsed_time/86400)
{
output = output.sprintf("%02u days %02u:%02u:%02u", elapsed_time/86400,
elapsed_time%86400/3600,
elapsed_time%3600/60,
elapsed_time%60);
}
else
{
output = output.sprintf("%02u:%02u:%02u", elapsed_time%86400/3600,
elapsed_time%3600/60,
elapsed_time%60);
}
ui->lElapsed->setText(output);
}
/*============
* Capture groupbox
*============ */
if (summary_.shb_os)
{
ui->lOS->setText(summary_.shb_os);
}
if (summary_.shb_user_appl)
{
ui->lCaptureApp->setText(summary_.shb_user_appl);
}
if (wtap_dump_can_write(cfile.linktypes, WTAP_COMMENT_PER_SECTION))
{
ui->teCFComments->setText(summary_.opt_comment);
}
/*============
* Interfaces table
*============ */
ui->tbInterfaces->setRowCount(0);
for (i = 0; i < summary_.ifaces->len; i++)
{
ui->tbInterfaces->setRowCount(ui->tbInterfaces->rowCount() + 1);
iface = g_array_index(summary_.ifaces, iface_options, i);
/* interface */
if (iface.descr)
{
output = QString(iface.descr);
}
else if (iface.name)
{
output = QString(iface.name);
}
else
{
output = QString(tr("unknown"));
}
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, 0, new QTableWidgetItem(output));
/* Dropped count */
if (iface.drops_known)
{
output = QString("%1 (%2 %)").arg(iface.drops).arg(QString::number(
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
summary_.packet_count ?(100.0 * (gint64)iface.drops)/summary_.packet_count : 0.0f, 'g', 3));
}
else
{
output = QString(tr("Unknown"));
}
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, 1, new QTableWidgetItem(output));
/* Capture filter */
if (iface.cfilter && iface.cfilter[0] != '\0')
{
output = output.sprintf("%s", iface.cfilter);
}
else
{
if (iface.name)
{
output = QString(tr("none"));
}
else
{
output = QString(tr("unknown"));
}
}
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, 2, new QTableWidgetItem(output));
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, 3, new QTableWidgetItem(wtap_encap_string(iface.encap_type)));
output = output.sprintf(tr("%u bytes").toStdString().c_str(), iface.snap);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, 4, new QTableWidgetItem(output));
}
/*============
* Display table
*============ */
/* Display filter */
if (summary_.dfilter)
{
output = QString(summary_.dfilter);
}
else
{
output = QString(tr("none"));
}
ui->lDisplayFilter->setText(output);
/* Ignored packets */
output = output.sprintf("%i (%.3f%%)", summary_.ignored_count,
summary_.packet_count ? (100.0 * summary_.ignored_count)/summary_.packet_count : 0.0);
ui->lIgnoredPackets->setText(output);
/* filling the display table*/
ui->tbDisplay->setRowCount(0);
/*
* Packet count
**/
ui->tbDisplay->setRowCount(ui->tbDisplay->rowCount() + 1);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 0, new QTableWidgetItem(tr("Packets")));
output = output.sprintf("%i", summary_.packet_count);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 1, new QTableWidgetItem(output));
if (summary_.dfilter)
{
output = output.sprintf("%i (%.3f%%)", summary_.filtered_count,
summary_.packet_count ?
(100.0 * summary_.filtered_count)/summary_.packet_count : 0.0);
}
else
{
output = output.sprintf("%i (100.000%%)", summary_.packet_count);
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 2, new QTableWidgetItem(output));
output = output.sprintf("%i (%.3f%%)", summary_.marked_count,
summary_.packet_count ?
(100.0 * summary_.marked_count)/summary_.packet_count : 0.0);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 3, new QTableWidgetItem(output));
/*
* Time between first and last
**/
ui->tbDisplay->setRowCount(ui->tbDisplay->rowCount() + 1);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 0, new QTableWidgetItem(tr("Between first and last packet")));
if (seconds > 0)
{
output = output.sprintf(tr("%.3f sec").toStdString().c_str(), seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 1, new QTableWidgetItem(output));
/* Displayed packet count */
if (summary_.dfilter && disp_seconds > 0)
{
output = output.sprintf(tr("%.3f sec").toStdString().c_str(), disp_seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 2, new QTableWidgetItem(output));
/* Marked packet count */
if (summary_.marked_count && marked_seconds > 0)
{
output = output.sprintf(tr("%.3f sec").toStdString().c_str(), marked_seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 3, new QTableWidgetItem(output));
/*
* Average packets per second
**/
ui->tbDisplay->setRowCount(ui->tbDisplay->rowCount() + 1);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 0, new QTableWidgetItem(tr("Avg. packets/sec")));
if (seconds > 0)
{
output = output.sprintf("%.3f", summary_.packet_count/seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 1, new QTableWidgetItem(output));
/* Displayed packet count/sec */
if (summary_.dfilter && disp_seconds > 0)
{
output = output.sprintf("%.3f", summary_.filtered_count/disp_seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 2, new QTableWidgetItem(output));
/* Marked packet count/sec */
if (summary_.marked_count && marked_seconds > 0)
{
output = output.sprintf("%.3f", summary_.marked_count/marked_seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 3, new QTableWidgetItem(output));
/*
* Average packet size
**/
ui->tbDisplay->setRowCount(ui->tbDisplay->rowCount() + 1);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 0, new QTableWidgetItem(tr("Avg. packet size")));
if (summary_.packet_count > 1)
{
output = output.sprintf(tr("%.3f bytes").toStdString().c_str(),
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
(float) ((gint64) summary_.bytes)/summary_.packet_count);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 1, new QTableWidgetItem(output));
if (summary_.dfilter && summary_.filtered_count > 1)
{
output = output.sprintf(tr("%.3f bytes").toStdString().c_str(),
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
(float) ((gint64) summary_.filtered_bytes)/summary_.filtered_count);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 2, new QTableWidgetItem(output));
if (summary_.marked_count > 1)
{
output = output.sprintf(tr("%.3f bytes").toStdString().c_str(),
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
(float) ((gint64) summary_.marked_bytes)/summary_.marked_count);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 3, new QTableWidgetItem(output));
/*
* Byte count
**/
ui->tbDisplay->setRowCount(ui->tbDisplay->rowCount() + 1);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 0, new QTableWidgetItem(tr("Bytes")));
output = QString("%1").arg(summary_.bytes);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 1, new QTableWidgetItem(output));
if (summary_.dfilter)
{
output = QString("%1 (%2%)").arg(summary_.filtered_bytes).arg(QString::number(
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
summary_.bytes ?(100.0 * (gint64)summary_.filtered_bytes)/summary_.bytes : 0.0f, 'g', 3));
}
else
{
output = QString("%1 (100.000%)").arg(summary_.bytes);
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 2, new QTableWidgetItem(output));
if (summary_.marked_count)
{
output = QString("%1 (%2%)").arg(summary_.marked_bytes).arg(QString::number(
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
summary_.bytes ?(100.0 * (gint64)summary_.marked_bytes)/summary_.bytes : 0.0f, 'g', 3));
}
else
{
output = QString("0 (0.000%)");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 3, new QTableWidgetItem(output));
/*
* Bytes per second
**/
ui->tbDisplay->setRowCount(ui->tbDisplay->rowCount() + 1);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 0, new QTableWidgetItem(tr("Avg. bytes/sec")));
if (seconds > 0)
{
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
output = output.sprintf("%.3f", ((gint64) summary_.bytes)/seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 1, new QTableWidgetItem(output));
/* Displayed packet count/sec */
if (summary_.dfilter && disp_seconds > 0)
{
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
output = output.sprintf("%.3f", ((gint64) summary_.filtered_bytes)/disp_seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 2, new QTableWidgetItem(output));
/* Marked packet count/sec */
if (summary_.marked_count && marked_seconds > 0)
{
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
output = output.sprintf("%.3f", ((gint64) summary_.marked_bytes)/marked_seconds);
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 3, new QTableWidgetItem(output));
/*
* MBits per second
**/
ui->tbDisplay->setRowCount(ui->tbDisplay->rowCount() + 1);
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 0, new QTableWidgetItem(tr("Avg. MBit/sec")));
if (seconds > 0)
{
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
output = output.sprintf("%.3f", ((gint64) summary_.bytes) * 8.0 / (seconds * 1000.0 * 1000.0));
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 1, new QTableWidgetItem(output));
/* Displayed packet count/sec */
if (summary_.dfilter && disp_seconds > 0)
{
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
output = output.sprintf("%.3f", ((gint64) summary_.filtered_bytes) * 8.0 / (disp_seconds * 1000.0 * 1000.0));
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 2, new QTableWidgetItem(output));
/* Marked packet count/sec */
if (summary_.marked_count && marked_seconds > 0)
{
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
output = output.sprintf("%.3f", ((gint64) ((gint64) summary_.marked_bytes) * 8.0 / (marked_seconds * 1000.0 * 1000.0)));
}
else
{
output = QString("N/A");
}
ui->tbDisplay->setItem(ui->tbDisplay->rowCount()-1, 3, new QTableWidgetItem(output));
}
SummaryDialog::~SummaryDialog()
{
delete ui;
}
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

103
ui/qt/summary_dialog.h Normal file
View File

@ -0,0 +1,103 @@
/* summary_dialog.h
*
* GSoC 2013 - QtShark
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef SUMMARY_DIALOG_H
#define SUMMARY_DIALOG_H
#include <QDialog>
#include <QClipboard>
#include <string.h>
#include <time.h>
#include "config.h"
#include "qt_ui_utils.h"
#include <epan/strutil.h>
#include <wiretap/wtap.h>
#include "globals.h"
#include "file.h"
#include "summary.h"
#include "version_info.h"
#ifdef HAVE_LIBPCAP
#include "capture.h"
#include "ui/capture_globals.h"
#include "capture-pcap-util.h"
#endif
namespace Ui {
class SummaryDialog;
}
class SummaryDialog : public QDialog
{
Q_OBJECT
public:
explicit SummaryDialog(QWidget *parent = 0);
~SummaryDialog();
QString TimeToString(time_t ti_time);
void UpdateValues();
QString SummaryToString();
signals:
void captureCommentChanged();
protected slots:
void on_bRefresh_clicked();
void on_bSaveComments_clicked();
void on_bHelpButton_clicked();
void on_bCopyComment_clicked();
void on_tabWidget_currentChanged(int index);
private:
Ui::SummaryDialog *ui;
summary_tally summary_;
};
#endif
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

485
ui/qt/summary_dialog.ui Normal file
View File

@ -0,0 +1,485 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SummaryDialog</class>
<widget class="QDialog" name="SummaryDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>585</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Wireshark - Summary</string>
</property>
<property name="windowIcon">
<iconset resource="../../image/toolbar.qrc">
<normaloff>:/menu/help/wsicon16.png</normaloff>:/menu/help/wsicon16.png</iconset>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>781</width>
<height>531</height>
</rect>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>File capture details</string>
</attribute>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>761</width>
<height>111</height>
</rect>
</property>
<property name="title">
<string>File</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>21</x>
<y>21</y>
<width>731</width>
<height>80</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lFilename">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Length</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lLength">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Format</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="lFormat">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Encapsulation</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="lEncapsulation">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>10</x>
<y>140</y>
<width>761</width>
<height>91</height>
</rect>
</property>
<property name="title">
<string>Time</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>22</x>
<y>22</y>
<width>731</width>
<height>67</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>First packet</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lFirstPacket">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Last packet</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lLastPacket">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Elapsed</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="lElapsed">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_3">
<property name="geometry">
<rect>
<x>10</x>
<y>240</y>
<width>761</width>
<height>261</height>
</rect>
</property>
<property name="title">
<string>Capture</string>
</property>
<widget class="QTextEdit" name="teCFComments">
<property name="geometry">
<rect>
<x>20</x>
<y>100</y>
<width>731</width>
<height>151</height>
</rect>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
</widget>
<widget class="QLabel" name="label_17">
<property name="geometry">
<rect>
<x>20</x>
<y>80</y>
<width>271</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Capture file comments</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>21</x>
<y>18</y>
<width>731</width>
<height>38</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>OS</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lOS">
<property name="text">
<string>Unknown</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Capture app</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lCaptureApp">
<property name="text">
<string>Unknown</string>
</property>
</widget>
</item>
</layout>
</widget>
<zorder>layoutWidget</zorder>
<zorder>teCFComments</zorder>
<zorder>label_17</zorder>
</widget>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Capture statistics</string>
</attribute>
<widget class="QTableWidget" name="tbDisplay">
<property name="geometry">
<rect>
<x>10</x>
<y>210</y>
<width>751</width>
<height>271</height>
</rect>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="rowCount">
<number>0</number>
</property>
<property name="columnCount">
<number>4</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Traffic</string>
</property>
</column>
<column>
<property name="text">
<string>Captured</string>
</property>
</column>
<column>
<property name="text">
<string>Displayed</string>
</property>
</column>
<column>
<property name="text">
<string>Marked</string>
</property>
</column>
</widget>
<widget class="QTableWidget" name="tbInterfaces">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>751</width>
<height>151</height>
</rect>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="rowCount">
<number>0</number>
</property>
<property name="columnCount">
<number>5</number>
</property>
<column>
<property name="text">
<string>Interface</string>
</property>
</column>
<column>
<property name="text">
<string>Dropped packets</string>
</property>
</column>
<column>
<property name="text">
<string>Capture filter</string>
</property>
</column>
<column>
<property name="text">
<string>Link size</string>
</property>
</column>
<column>
<property name="text">
<string>Packet size limit</string>
</property>
</column>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>30</x>
<y>170</y>
<width>731</width>
<height>38</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Display filter</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lDisplayFilter">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Ignored packets</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lIgnoredPackets">
<property name="text">
<string>/</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Comment summary</string>
</attribute>
<widget class="QPlainTextEdit" name="pteCommentSummary">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>751</width>
<height>471</height>
</rect>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
</widget>
<widget class="QSplitter" name="splitter">
<property name="geometry">
<rect>
<x>20</x>
<y>550</y>
<width>771</width>
<height>23</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QPushButton" name="bRefresh">
<property name="text">
<string>Refresh</string>
</property>
</widget>
<widget class="QPushButton" name="bSaveComments">
<property name="text">
<string>Save </string>
</property>
</widget>
<widget class="QPushButton" name="bHelpButton">
<property name="text">
<string>Help</string>
</property>
</widget>
<widget class="QPushButton" name="bCopyComment">
<property name="text">
<string>Copy to clipboard</string>
</property>
</widget>
</widget>
</widget>
<resources>
<include location="../../image/toolbar.qrc"/>
</resources>
<connections/>
</ui>