Update the interface list to reflect the recent interface name changes.

Allow multiple interface selections. Make sure we update the packet list
properly in a couple of places.

Use the right callback+signal to update capture statistics in the status
bar. Remove the global cfile from the main_statusbar.cpp

Add the version to the main window.

svn path=/trunk/; revision=46350
This commit is contained in:
Gerald Combs 2012-12-03 19:58:55 +00:00
parent cef4af718c
commit 9e67335ea8
12 changed files with 162 additions and 77 deletions

View File

@ -27,8 +27,6 @@
#include "ui/iface_lists.h"
#include "ui/utf8_entities.h"
#include "epan/prefs.h"
#include "sparkline_delegate.h"
#include "wireshark_application.h"
@ -49,6 +47,7 @@ InterfaceTree::InterfaceTree(QWidget *parent) :
setRootIsDecorated(false);
setUniformRowHeights(true);
setColumnCount(2);
setSelectionMode(QAbstractItemView::ExtendedSelection);
setAccessibleName(tr("Welcome screen list"));
setItemDelegateForColumn(1, new SparkLineDelegate());
@ -59,7 +58,8 @@ InterfaceTree::InterfaceTree(QWidget *parent) :
addTopLevelItem(ti);
resizeColumnToContents(0);
connect (wsApp, SIGNAL(appInitialized()), this, SLOT(getInterfaceList()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(getInterfaceList()));
connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(updateSelectedInterfaces()));
}
InterfaceTree::~InterfaceTree() {
@ -120,30 +120,30 @@ void InterfaceTree::getInterfaceList()
// XXX Do we need to check for this? capture_interface_list returns an error if the length is 0.
if (g_list_length(if_list) > 0) {
if_info_t *if_info;
GList *curr;
interface_t device;
setDisabled(false);
for (curr = g_list_first(if_list); curr; curr = g_list_next(curr)) {
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
QList<int> *points;
QVariant v;
if_info = (if_info_t *) curr->data;
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
/* Continue if capture device is hidden */
if (prefs_is_capture_device_hidden(if_info->name)) {
if (device.hidden) {
continue;
}
QTreeWidgetItem *ti = new QTreeWidgetItem();
// XXX Using if_info->name is amazingly ugly under Windows but it's needed for
// statistics updates
// ti->setText(0, QString().fromUtf8(if_info->vendor_description ? if_info->vendor_description : if_info->name));
ti->setText(0, QString().fromUtf8(if_info->name));
ti->setText(0, QString().fromUtf8(device.display_name));
ti->setData(0, Qt::UserRole, QString(device.name));
points = new QList<int>();
v.setValue(points);
ti->setData(1, Qt::UserRole, v);
ti->setData(1, Qt::UserRole, qVariantFromValue(points));
addTopLevelItem(ti);
// XXX Add other device information
resizeColumnToContents(1);
if (device.selected) {
ti->setSelected(true);
}
}
}
free_interface_list(if_list);
@ -171,11 +171,11 @@ void InterfaceTree::updateStatistics(void) {
QTreeWidgetItemIterator iter(this);
while (*iter) {
QList<int> *points;
QVariant v;
for (if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
if ((*iter)->text(0).compare(QString().fromUtf8(device.name)) || device.hidden || device.type == IF_PIPE)
QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
if (device_name.compare(device.name) || device.hidden || device.type == IF_PIPE)
continue;
diff = 0;
@ -186,8 +186,7 @@ void InterfaceTree::updateStatistics(void) {
device.last_packets = stats.ps_recv;
}
v = (*iter)->data(1, Qt::UserRole);
points = v.value<QList<int> *>();
points = (*iter)->data(1, Qt::UserRole).value<QList<int> *>();
points->append(diff);
update(indexFromItem((*iter), 1));
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, if_idx);
@ -197,6 +196,41 @@ void InterfaceTree::updateStatistics(void) {
}
}
void InterfaceTree::updateSelectedInterfaces()
{
QTreeWidgetItemIterator iter(this);
global_capture_opts.num_selected = 0;
while (*iter) {
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device_name.compare(QString().fromUtf8(device.name)) == 0) {
if (!device.locked) {
if ((*iter)->isSelected()) {
device.selected = TRUE;
global_capture_opts.num_selected++;
} else {
device.selected = FALSE;
}
device.locked = TRUE;
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
emit interfaceUpdated(device.name, device.selected);
device.locked = FALSE;
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
}
break;
}
}
iter++;
}
}
/*
* Editor modelines
*

View File

@ -53,12 +53,17 @@ private:
QTimer *stat_timer_;
signals:
void interfaceUpdated(const char *device_name, bool selected);
public slots:
// add_interface_to_list
// change_interface_selection
// change_interface_selection_for_all
private slots:
void getInterfaceList();
void updateStatistics(void);
void updateSelectedInterfaces();
};
#endif // INTERFACE_TREE_H

View File

@ -27,10 +27,6 @@
#include "main_status_bar.h"
#include "wireshark_application.h"
#include "globals.h"
#include "epan/expert.h"
#include "ui/main_statusbar.h"
@ -42,9 +38,9 @@
#include "tango_colors.h"
#ifdef HAVE_LIBPCAP
#define DEF_READY_MESSAGE QObject::tr("Ready to load or capture")
#define DEF_READY_MESSAGE tr("Ready to load or capture")
#else
#define DEF_READY_MESSAGE QObject::tr("Ready to load file")
#define DEF_READY_MESSAGE tr("Ready to load file")
#endif
// XXX - The GTK+ code assigns priorities to these and pushes/pops accordingly.
@ -89,43 +85,12 @@ statusbar_push_temporary_msg(const gchar *msg_format, ...)
void
packets_bar_update(void)
{
QString packetsStr = QString("");
if (!cur_main_status_bar_) return;
cur_main_status_bar_->popPacketStatus();
/* Do we have any packets? */
if (cfile.count) {
packetsStr.append(QString(QObject::tr("Packets: %1 %4 Displayed: %2 %4 Marked: %3"))
.arg(cfile.count)
.arg(cfile.displayed_count)
.arg(cfile.marked_count)
.arg(UTF8_MIDDLE_DOT));
if(cfile.drops_known) {
packetsStr.append(QString(QObject::tr(" %1 Dropped: %2"))).arg(UTF8_MIDDLE_DOT).arg(cfile.drops);
}
if(cfile.ignored_count > 0) {
packetsStr.append(QString(QObject::tr(" %1 Ignored: %2")).arg(UTF8_MIDDLE_DOT).arg(cfile.ignored_count));
}
if(!cfile.is_tempfile) {
/* Loading an existing file */
gulong computed_elapsed = cf_get_computed_elapsed();
packetsStr.append(QString(QObject::tr(" %1 Load time: %2:%3.%4"))
.arg(UTF8_MIDDLE_DOT)
.arg(computed_elapsed/60000)
.arg(computed_elapsed%60000/1000)
.arg(computed_elapsed%1000));
}
} else {
packetsStr.append(QObject::tr("No Packets"));
}
cur_main_status_bar_->pushPacketStatus(packetsStr);
// XXX Implement
}
MainStatusBar::MainStatusBar(QWidget *parent) :
QStatusBar(parent)
QStatusBar(parent),
cap_file_(NULL)
{
QSplitter *splitter = new QSplitter(this);
QString ready_msg(DEF_READY_MESSAGE);
@ -178,6 +143,8 @@ MainStatusBar::MainStatusBar(QWidget *parent) :
connect(wsApp, SIGNAL(appInitialized()), splitter, SLOT(show()));
connect(&info_status_, SIGNAL(toggleTemporaryFlash(bool)),
this, SLOT(toggleBackground(bool)));
connect(wsApp, SIGNAL(captureCaptureUpdateContinue(capture_options*)),
this, SLOT(updateCaptureStatistics(capture_options*)));
}
void MainStatusBar::showExpert() {
@ -224,6 +191,11 @@ void MainStatusBar::expertUpdate() {
expert_status_.show();
}
void MainStatusBar::setCaptureFile(capture_file *cf)
{
cap_file_ = cf;
}
void MainStatusBar::pushTemporaryStatus(QString &message) {
info_status_.pushText(message, STATUS_CTX_TEMPORARY);
}
@ -292,6 +264,42 @@ void MainStatusBar::toggleBackground(bool enabled)
}
}
void MainStatusBar::updateCaptureStatistics(capture_options *capture_opts)
{
QString packets_str;
if (capture_opts->cf != cap_file_ || !cap_file_) return;
/* Do we have any packets? */
if (cap_file_->count) {
packets_str.append(QString(tr("Packets: %1 %4 Displayed: %2 %4 Marked: %3"))
.arg(cap_file_->count)
.arg(cap_file_->displayed_count)
.arg(cap_file_->marked_count)
.arg(UTF8_MIDDLE_DOT));
if(cap_file_->drops_known) {
packets_str.append(QString(tr(" %1 Dropped: %2")).arg(UTF8_MIDDLE_DOT).arg(cap_file_->drops));
}
if(cap_file_->ignored_count > 0) {
packets_str.append(QString(tr(" %1 Ignored: %2")).arg(UTF8_MIDDLE_DOT).arg(cap_file_->ignored_count));
}
if(!cap_file_->is_tempfile) {
/* Loading an existing file */
gulong computed_elapsed = cf_get_computed_elapsed();
packets_str.append(QString(tr(" %1 Load time: %2:%3.%4"))
.arg(UTF8_MIDDLE_DOT)
.arg(computed_elapsed/60000)
.arg(computed_elapsed%60000/1000)
.arg(computed_elapsed%1000));
}
} else {
packets_str.append(tr("No Packets"));
}
popPacketStatus();
pushPacketStatus(packets_str);
}
/*
* Editor modelines
*

View File

@ -24,12 +24,15 @@
#ifndef MAIN_STATUS_BAR_H
#define MAIN_STATUS_BAR_H
#include "wireshark_application.h"
#include "label_stack.h"
#include "progress_bar.h"
#include <QStatusBar>
#include <QLabel>
#include "cfile.h"
class MainStatusBar : public QStatusBar
{
Q_OBJECT
@ -44,12 +47,14 @@ private:
ProgressBar progress_bar_;
LabelStack packet_status_;
LabelStack profile_status_;
capture_file *cap_file_;
void expertUpdate();
signals:
public slots:
void setCaptureFile(capture_file *cf);
void pushTemporaryStatus(QString &message);
void popTemporaryStatus();
void pushFileStatus(QString &message);
@ -65,6 +70,7 @@ public slots:
private slots:
void toggleBackground(bool enabled);
void updateCaptureStatistics(capture_options * capture_opts);
};
#endif // MAIN_STATUS_BAR_H

View File

@ -51,15 +51,12 @@ MainWelcome::MainWelcome(QWidget *parent) :
// QGridLayout *grid = new QGridLayout(this);
// QVBoxLayout *column;
// QLabel *heading;
#ifdef Q_WS_MAC
InterfaceTree *iface_tree;
#endif
welcome_ui_->setupUi(this);
welcome_ui_->mainWelcomeBanner->setText("Wireshark<br><small>" VERSION "</small>");
task_list_ = welcome_ui_->taskList;
#ifdef Q_WS_MAC
iface_tree = welcome_ui_->interfaceTree;
#endif
recent_files_ = welcome_ui_->recentList;
setStyleSheet(QString(
@ -103,7 +100,7 @@ MainWelcome::MainWelcome(QWidget *parent) :
#ifdef Q_WS_MAC
recent_files_->setAttribute(Qt::WA_MacShowFocusRect, false);
welcome_ui_->taskList->setAttribute(Qt::WA_MacShowFocusRect, false);
iface_tree->setAttribute(Qt::WA_MacShowFocusRect, false);
welcome_ui_->interfaceTree->setAttribute(Qt::WA_MacShowFocusRect, false);
#endif
task_list_->setStyleSheet(
@ -138,6 +135,8 @@ MainWelcome::MainWelcome(QWidget *parent) :
connect(wsApp, SIGNAL(updateRecentItemStatus(const QString &, qint64, bool)), this, SLOT(updateRecentFiles()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(destroySplashOverlay()));
connect(task_list_, SIGNAL(itemSelectionChanged()), this, SLOT(showTask()));
connect(welcome_ui_->interfaceTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
this, SLOT(interfaceDoubleClicked(QTreeWidgetItem*,int)));
connect(recent_files_, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(openRecentItem(QListWidgetItem *)));
updateRecentFiles();
@ -166,6 +165,15 @@ void MainWelcome::showTask() {
welcome_ui_->taskStack->setCurrentIndex(task_list_->currentRow());
}
void MainWelcome::interfaceDoubleClicked(QTreeWidgetItem *item, int column)
{
Q_UNUSED(column);
if (item) {
emit startCapture();
}
}
void MainWelcome::updateRecentFiles() {
QString itemLabel;
QListWidgetItem *rfItem;

View File

@ -26,6 +26,7 @@
#include <QFrame>
#include <QListWidget>
#include <QTreeWidgetItem>
#include "splash_overlay.h"
@ -54,14 +55,15 @@ private:
signals:
void startCapture();
void recentFileActivated(QString& cfile);
private slots:
void destroySplashOverlay();
void showTask();
void interfaceDoubleClicked(QTreeWidgetItem *item, int column);
void updateRecentFiles();
void openRecentItem(QListWidgetItem *item);
};
#endif // MAIN_WELCOME_H

View File

@ -133,7 +133,7 @@ more about Wireshark</string>
</sizepolicy>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wireshark&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string/>
</property>
</widget>
</item>

View File

@ -90,6 +90,7 @@ MainWindow::MainWindow(QWidget *parent) :
setMenusForSelectedTreeRow();
setForCaptureInProgress(false);
setMenusForFileSet(false);
interfaceSelectionChanged();
connect(wsApp, SIGNAL(updateRecentItemStatus(const QString &, qint64, bool)), this, SLOT(updateRecentFiles()));
updateRecentFiles();
@ -181,9 +182,13 @@ MainWindow::MainWindow(QWidget *parent) :
connect(wsApp, SIGNAL(captureFileClosed(const capture_file*)),
this, SLOT(captureFileClosed(const capture_file*)));
connect(main_welcome_, SIGNAL(startCapture()),
this, SLOT(startCapture()));
connect(main_welcome_, SIGNAL(recentFileActivated(QString&)),
this, SLOT(openCaptureFile(QString&)));
connect(this, SIGNAL(setCaptureFile(capture_file*)),
main_ui_->statusBar, SLOT(setCaptureFile(capture_file*)));
connect(this, SIGNAL(setCaptureFile(capture_file*)),
packet_list_, SLOT(setCaptureFile(capture_file*)));
connect(this, SIGNAL(setCaptureFile(capture_file*)),
@ -214,6 +219,11 @@ MainWindow::MainWindow(QWidget *parent) :
connect(&file_set_dialog_, SIGNAL(fileSetOpenCaptureFile(QString&)),
this, SLOT(openCaptureFile(QString&)));
QTreeWidget *iface_tree = findChild<QTreeWidget *>("interfaceTree");
if (iface_tree) {
connect(iface_tree, SIGNAL(itemSelectionChanged()),
this, SLOT(interfaceSelectionChanged()));
}
main_ui_->mainStack->setCurrentWidget(main_welcome_);
}
@ -443,8 +453,10 @@ void MainWindow::mergeCaptureFile()
cf_close(cap_file_);
/* Try to open the merged capture file. */
cfile.window = this;
if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) != CF_OK) {
/* We couldn't open it; fail. */
cfile.window = NULL;
if (rfcode != NULL)
dfilter_free(rfcode);
g_free(tmpname);

View File

@ -151,6 +151,7 @@ private slots:
void updateRecentFiles();
void recentActionTriggered();
void setMenusForSelectedTreeRow(field_info *fi = NULL);
void interfaceSelectionChanged();
void on_actionFileOpen_triggered();
void on_actionFileMerge_triggered();

View File

@ -328,8 +328,7 @@ void MainWindow::startCapture() {
guint i;
/* did the user ever select a capture interface before? */
if(global_capture_opts.num_selected == 0 &&
((prefs.capture_device == NULL) || (*prefs.capture_device != '\0'))) {
if(global_capture_opts.num_selected == 0) {
QString msg = QString("No interface selected");
main_ui_->statusBar->pushTemporaryStatus(msg);
return;
@ -349,6 +348,7 @@ void MainWindow::startCapture() {
this capture. */
collect_ifaces(&global_capture_opts);
cfile.window = this;
if (capture_start(&global_capture_opts)) {
/* The capture succeeded, which means the capture filter syntax is
valid; add this capture filter to the recent capture filter list. */
@ -358,6 +358,8 @@ void MainWindow::startCapture() {
// cfilter_combo_add_recent(interface_opts.cfilter);
}
}
} else {
cfile.window = NULL;
}
}
@ -617,6 +619,15 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
}
}
void MainWindow::interfaceSelectionChanged()
{
if (global_capture_opts.num_selected > 0) {
main_ui_->actionStartCapture->setEnabled(true);
} else {
main_ui_->actionStartCapture->setEnabled(false);
}
}
// File Menu
@ -970,12 +981,8 @@ void MainWindow::on_actionStartCapture_triggered()
main_ui_->mainStack->setCurrentWidget(packet_splitter_);
if (global_capture_opts.num_selected == 0) {
QMessageBox::critical(
this,
tr("No Interface Selected"),
tr("You didn't specify an interface on which to capture packets."),
QMessageBox::Ok
);
QString err_msg = tr("No Interface Selected");
main_ui_->statusBar->pushTemporaryStatus(err_msg);
return;
}

View File

@ -182,7 +182,8 @@ void WiresharkApplication::captureCallback(int event, capture_options * capture_
emit captureCaptureUpdateStarted(capture_opts);
break;
case(capture_cb_capture_update_continue):
/*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");
emit captureCaptureUpdateContinue(capture_opts);
break;
case(capture_cb_capture_update_finished):
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");

View File

@ -91,6 +91,7 @@ signals:
// XXX It might make more sense to move these to main.cpp or main_window.cpp or their own class.
void captureCapturePrepared(capture_options *capture_opts);
void captureCaptureUpdateStarted(capture_options *capture_opts);
void captureCaptureUpdateContinue(capture_options *capture_opts);
void captureCaptureUpdateFinished(capture_options *capture_opts);
void captureCaptureFixedStarted(capture_options *capture_opts);
void captureCaptureFixedFinished(capture_options *capture_opts);