Initial status bar functionality. Promote the main window's status bar

to a MainStatusBar. Add a "LabelStack" widget, which MainStatusBar uses
to duplicate features in GtkStatusbar. Make the protocol tree a
full-blown ProtoTree widget. Move main_cf_callback from main to
WiresharkApplication. Duplicate a lot of the cf callbacks as signals and
slots. Use Q_UNUSED in a few places.

svn path=/trunk/; revision=40488
This commit is contained in:
Gerald Combs 2012-01-14 00:16:16 +00:00
parent c7857a522b
commit bc957229f8
17 changed files with 607 additions and 153 deletions

View File

@ -105,6 +105,7 @@ SOURCES += \
recent_file_status.cpp \
simple_dialog_qt.cpp \
wireshark_application.cpp \
label_stack.cpp
unix:SOURCES += ../../capture-pcap-util-unix.c
@ -137,6 +138,7 @@ HEADERS += \
recent_file_status.h \
simple_dialog_qt.h \
wireshark_application.h \
label_stack.h
FORMS += main_window.ui

View File

@ -254,11 +254,11 @@ void DisplayFilterEdit::checkFilter(const QString& text)
clearButton->setVisible(!text.isEmpty());
popFilterSyntaxStatus();
if (fieldNameOnly && (c = proto_check_field_name(text.toUtf8().constData()))) {
m_syntaxState = Invalid;
// if (use_statusbar) {
// statusbar_push_filter_msg(" Illegal character in field name: '%c'", c);
// }
emit pushFilterSyntaxStatus(QString().sprintf("Illegal character in field name: '%c'", c));
} else if (dfilter_compile(text.toUtf8().constData(), &dfp)) {
if (dfp != NULL) {
depr = dfilter_deprecated_tokens(dfp);
@ -268,30 +268,25 @@ void DisplayFilterEdit::checkFilter(const QString& text)
} else if (depr) {
/* You keep using that word. I do not think it means what you think it means. */
m_syntaxState = Deprecated;
// if (use_statusbar) {
// /*
// * We're being lazy and only printing the first "problem" token.
// * Would it be better to print all of them?
// */
// statusbar_push_temporary_msg(" \"%s\" may have unexpected results (see the User's Guide)",
// (const char *) g_ptr_array_index(depr, 0));
// }
/*
* We're being lazy and only printing the first "problem" token.
* Would it be better to print all of them?
*/
emit pushFilterSyntaxWarning(QString().sprintf("\"%s\" may have unexpected results (see the User's Guide)",
(const char *) g_ptr_array_index(depr, 0)));
} else {
m_syntaxState = Valid;
}
dfilter_free(dfp);
} else {
m_syntaxState = Invalid;
// if (use_statusbar) {
// if (dfilter_error_msg) {
// statusbar_push_filter_msg(" Invalid filter: %s", dfilter_error_msg);
// } else {
// statusbar_push_filter_msg(" Invalid filter");
// }
// }
QString invalidMsg("Invalid filter");
if (dfilter_error_msg) {
invalidMsg.append(QString().sprintf(": %s", dfilter_error_msg));
}
emit pushFilterSyntaxStatus(invalidMsg);
}
g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: show display filter syntax status in statusbar");
setStyleSheet(syntaxStyleSheet);
applyButton->setEnabled(m_syntaxState == Empty || m_syntaxState == Valid);

View File

@ -59,6 +59,9 @@ private:
QToolButton *applyButton;
signals:
void pushFilterSyntaxStatus(QString&);
void popFilterSyntaxStatus();
void pushFilterSyntaxWarning(QString&);
public slots:

103
ui/qt/label_stack.cpp Normal file
View File

@ -0,0 +1,103 @@
/* label_stack.cpp
*
* $Id: mainStatus_bar.cpp 40378 2012-01-04 22:13:01Z gerald $
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "label_stack.h"
#include <QTimer>
/* Temporary message timeouts */
#define TEMPORARY_MSG_TIMEOUT (7 * 1000)
//#define TEMPORARY_FLASH_TIMEOUT (1 * 1000)
//#define TEMPORARY_FLASH_INTERVAL (TEMPORARY_FLASH_TIMEOUT / 4)
LabelStack::LabelStack(QWidget *parent) :
QLabel(parent)
{
m_temporaryCtx = -1;
fillLabel();
}
void LabelStack::setTemporaryContext(int ctx) {
m_temporaryCtx = ctx;
}
void LabelStack::fillLabel() {
StackItem *si;
setStyleSheet(
"QLabel {"
" margin-left: 0.5em;"
"}"
);
if (m_labels.isEmpty()) {
clear();
return;
}
si = m_labels.first();
if (si->ctx == m_temporaryCtx) {
setStyleSheet(
// Tango "Scarlet Red"
"QLabel {"
" margin-left: 0.5em;"
" border-radius: 3px;"
" color: white;"
" background-color: rgba(239, 41, 41, 128);"
"}"
);
}
setText(si->text);
}
void LabelStack::pushText(QString &text, int ctx) {
StackItem *si = new StackItem;
si->text = text;
si->ctx = ctx;
m_labels.prepend(si);
if (ctx == m_temporaryCtx) {
QTimer::singleShot(TEMPORARY_MSG_TIMEOUT, this, SLOT(popTemporaryText()));
}
fillLabel();
}
void LabelStack::popText(int ctx) {
QMutableListIterator<StackItem *> iter(m_labels);
while (iter.hasNext()) {
if (iter.next()->ctx == ctx) {
iter.remove();
break;
}
}
fillLabel();
}
void LabelStack::popTemporaryText() {
popText(m_temporaryCtx);
}

58
ui/qt/label_stack.h Normal file
View File

@ -0,0 +1,58 @@
/* label_stack.h
*
* $Id: mainStatus_bar.cpp 40378 2012-01-04 22:13:01Z gerald $
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef LABEL_STACK_H
#define LABEL_STACK_H
#include <QLabel>
#include <QStack>
class LabelStack : public QLabel
{
Q_OBJECT
public:
explicit LabelStack(QWidget *parent = 0);
void setTemporaryContext(int ctx);
void pushText(QString &text, int ctx);
private:
typedef struct _StackItem {
QString text;
int ctx;
} StackItem;
int m_temporaryCtx;
QList<StackItem *> m_labels;
void fillLabel();
signals:
public slots:
void popText(int ctx);
private slots:
void popTemporaryText();
};
#endif // LABEL_STACK_H

View File

@ -173,52 +173,10 @@ void pipe_input_set_handler(gint source, gpointer user_data, int *child_process,
}
static void
main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
main_cf_callback(gint event, gpointer data, gpointer user_data )
{
g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: main_cf_callback %d %p", event, data);
// switch(event) {
// case(cf_cb_file_closing):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
// main_cf_cb_file_closing(data);
// break;
// case(cf_cb_file_closed):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
// main_cf_cb_file_closed(data);
// break;
// case(cf_cb_file_read_started):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
// main_cf_cb_file_read_started(data);
// break;
// case(cf_cb_file_read_finished):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
// main_cf_cb_file_read_finished(data);
// break;
// case(cf_cb_packet_selected):
// main_cf_cb_packet_selected(data);
// break;
// case(cf_cb_packet_unselected):
// main_cf_cb_packet_unselected(data);
// break;
// case(cf_cb_field_unselected):
// main_cf_cb_field_unselected(data);
// break;
// case(cf_cb_file_save_started):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
// break;
// case(cf_cb_file_save_finished):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
// break;
// case(cf_cb_file_save_reload_finished):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
// main_cf_cb_file_save_reload_finished(data);
// break;
// case(cf_cb_file_save_failed):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
// break;
// default:
// g_warning("main_cf_callback: event %u unknown", event);
// g_assert_not_reached();
// }
Q_UNUSED(user_data);
wsApp->captureFileCallback(event, data);
}
// XXX Copied from gtk/main.c. This should be moved to a common location.

View File

@ -29,12 +29,32 @@
#include "main_status_bar.h"
#include "main_statusbar.h"
#include "wireshark_application.h"
/* Temporary message timeouts */
#define TEMPORARY_MSG_TIMEOUT (7 * 1000)
#define TEMPORARY_FLASH_TIMEOUT (1 * 1000)
#define TEMPORARY_FLASH_INTERVAL (TEMPORARY_FLASH_TIMEOUT / 4)
#include "main_statusbar.h"
#include "globals.h"
#include <QSplitter>
#ifdef HAVE_LIBPCAP
#define DEF_READY_MESSAGE " Ready to load or capture"
#else
#define DEF_READY_MESSAGE " Ready to load file"
#endif
// XXX - The GTK+ code assigns priorities to these and pushes/pops accordingly.
enum StatusContext {
STATUS_CTX_MAIN,
STATUS_CTX_FILE,
STATUS_CTX_FIELD,
STATUS_CTX_FILTER,
STATUS_CTX_TEMPORARY
};
// If we ever add support for multiple windows this will need to be replaced.
// See also: main_window.cpp
static MainStatusBar *cur_main_status_bar = NULL;
/*
* Push a formatted temporary message onto the statusbar.
@ -44,21 +64,18 @@ statusbar_push_temporary_msg(const gchar *msg_format, ...)
{
va_list ap;
gchar *msg;
guint msg_id;
QString pushMsg;
if (!cur_main_status_bar) return;
va_start(ap, msg_format);
msg = g_strdup_vprintf(msg_format, ap);
va_end(ap);
g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: statusbar_push_temporary_msg: %s", msg);
// msg_id = gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, msg);
pushMsg.fromUtf8(msg);
g_free(msg);
// flash_time = TEMPORARY_FLASH_TIMEOUT - 1;
// g_timeout_add(TEMPORARY_FLASH_INTERVAL, statusbar_flash_temporary_msg, NULL);
// g_timeout_add(TEMPORARY_MSG_TIMEOUT, statusbar_remove_temporary_msg, GUINT_TO_POINTER(msg_id));
cur_main_status_bar->pushTemporaryStatus(pushMsg);
}
/*
@ -67,41 +84,109 @@ statusbar_push_temporary_msg(const gchar *msg_format, ...)
void
packets_bar_update(void)
{
g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: packets_bar_update");
// if(packets_bar) {
// /* Remove old status */
// if(packets_str) {
// gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
// } else {
// packets_str = g_string_new ("");
// }
QString packetsStr = QString("");
// /* Do we have any packets? */
// if(cfile.count) {
// g_string_printf(packets_str, " Packets: %u Displayed: %u Marked: %u",
// cfile.count, cfile.displayed_count, cfile.marked_count);
// if(cfile.drops_known) {
// g_string_append_printf(packets_str, " Dropped: %u", cfile.drops);
// }
// if(cfile.ignored_count > 0) {
// g_string_append_printf(packets_str, " Ignored: %u", cfile.ignored_count);
// }
// if(!cfile.is_tempfile){
// /* Loading an existing file */
// gulong computed_elapsed = cf_get_computed_elapsed();
// g_string_append_printf(packets_str, " Load time: %lu:%02lu.%03lu",
// computed_elapsed/60000,
// computed_elapsed%60000/1000,
// computed_elapsed%1000);
// }
// } else {
// g_string_printf(packets_str, " No Packets");
// }
// gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str->str);
// }
if (!cur_main_status_bar) return;
cur_main_status_bar->popPacketStatus();
/* Do we have any packets? */
if (cfile.count) {
packetsStr.append(QString("Packets: %1 Displayed: %2 Marked: %3")
.arg(cfile.count)
.arg(cfile.displayed_count)
.arg(cfile.marked_count));
if(cfile.drops_known) {
packetsStr.append(QString(" Dropped: %1").arg(cfile.drops));
}
if(cfile.ignored_count > 0) {
packetsStr.append(QString(" Ignored: %1").arg(cfile.ignored_count));
}
if(!cfile.is_tempfile) {
/* Loading an existing file */
gulong computed_elapsed = cf_get_computed_elapsed();
packetsStr.append(QString().sprintf(" Load time: %lu:%02lu.%03lu",
computed_elapsed/60000,
computed_elapsed%60000/1000,
computed_elapsed%1000));
}
} else {
packetsStr.append("No Packets");
}
cur_main_status_bar->pushPacketStatus(packetsStr);
}
MainStatusBar::MainStatusBar(QWidget *parent) :
QStatusBar(parent)
{
QSplitter *splitter = new QSplitter(this);
QString readyMsg(DEF_READY_MESSAGE);
// XXX - Add the expert level icon
m_infoStatus.setTemporaryContext(STATUS_CTX_TEMPORARY);
splitter->addWidget(&m_infoStatus);
splitter->addWidget(&m_packetStatus);
splitter->addWidget(&m_profileStatus);
splitter->setStretchFactor(0, 3);
splitter->setStretchFactor(1, 3);
splitter->setStretchFactor(2, 0);
addWidget(splitter, 1);
cur_main_status_bar = this;
m_infoStatus.pushText(readyMsg, STATUS_CTX_MAIN);
packets_bar_update();
}
void MainStatusBar::pushTemporaryStatus(QString &message) {
m_infoStatus.pushText(message, STATUS_CTX_TEMPORARY);
}
void MainStatusBar::popTemporaryStatus() {
m_infoStatus.popText(STATUS_CTX_TEMPORARY);
}
void MainStatusBar::pushFileStatus(QString &message) {
m_infoStatus.pushText(message, STATUS_CTX_FILE);
}
void MainStatusBar::popFileStatus() {
m_infoStatus.popText(STATUS_CTX_FILE);
}
void MainStatusBar::pushFieldStatus(QString &message) {
m_infoStatus.pushText(message, STATUS_CTX_FIELD);
}
void MainStatusBar::popFieldStatus() {
m_infoStatus.popText(STATUS_CTX_FIELD);
}
void MainStatusBar::pushFilterStatus(QString &message) {
m_infoStatus.pushText(message, STATUS_CTX_FILTER);
}
void MainStatusBar::popFilterStatus() {
m_infoStatus.popText(STATUS_CTX_FILTER);
}
void MainStatusBar::pushPacketStatus(QString &message) {
m_packetStatus.pushText(message, STATUS_CTX_MAIN);
}
void MainStatusBar::popPacketStatus() {
m_packetStatus.popText(STATUS_CTX_MAIN);
}
void MainStatusBar::pushProfileStatus(QString &message) {
m_profileStatus.pushText(message, STATUS_CTX_MAIN);
}
void MainStatusBar::popProfileStatus() {
m_profileStatus.popText(STATUS_CTX_MAIN);
}

View File

@ -1,4 +1,4 @@
/* main_status_bar.h
/* mainStatus_bar.h
*
* $Id$
*
@ -21,8 +21,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef MAIN_STATUS_BAR_H
#define MAIN_STATUS_BAR_H
#ifndef MAINStatus_BAR_H
#define MAINStatus_BAR_H
#include "label_stack.h"
#include <QStatusBar>
@ -32,10 +34,26 @@ class MainStatusBar : public QStatusBar
public:
explicit MainStatusBar(QWidget *parent = 0);
private:
LabelStack m_infoStatus;
LabelStack m_packetStatus;
LabelStack m_profileStatus;
signals:
public slots:
void pushTemporaryStatus(QString &message);
void popTemporaryStatus();
void pushFileStatus(QString &message);
void popFileStatus();
void pushFieldStatus(QString &message);
void popFieldStatus();
void pushFilterStatus(QString &message);
void popFilterStatus();
void pushPacketStatus(QString &message);
void popPacketStatus();
void pushProfileStatus(QString &message);
void popProfileStatus();
};
#endif // MAIN_STATUS_BAR_H
#endif // MAINStatus_BAR_H

View File

@ -24,16 +24,19 @@
#include "main_window.h"
#include "ui_main_window.h"
#include "config.h"
#include <glib.h>
#include "globals.h"
#include <epan/filesystem.h>
#include <epan/prefs.h>
#include "main_statusbar.h"
#include "wireshark_application.h"
#include "packet_list.h"
#include "proto_tree.h"
#include "byte_view_tab.h"
#include "capture_file_dialog.h"
#include "display_filter_edit.h"
#include "qt_ui_utils.h"
@ -43,8 +46,6 @@
#include <QToolButton>
#include <QKeyEvent>
#include "globals.h"
//menu_recent_file_write_all
// If we ever add support for multiple windows this will need to be replaced.
@ -54,6 +55,7 @@ MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
capFile = NULL;
cur_main_window = this;
ui->setupUi(this);
@ -61,6 +63,10 @@ MainWindow::MainWindow(QWidget *parent) :
updateRecentFiles();
dfComboBox = new DisplayFilterCombo();
const DisplayFilterEdit *dfEdit = dynamic_cast<DisplayFilterEdit *>(dfComboBox->lineEdit());
connect(dfEdit, SIGNAL(pushFilterSyntaxStatus(QString&)), ui->statusBar, SLOT(pushFilterStatus(QString&)));
connect(dfEdit, SIGNAL(popFilterSyntaxStatus()), ui->statusBar, SLOT(popFilterStatus()));
connect(dfEdit, SIGNAL(pushFilterSyntaxWarning(QString&)), ui->statusBar, SLOT(pushTemporaryStatus(QString&)));
#ifdef _WIN32
// Qt <= 4.7 doesn't seem to style Windows toolbars. If we wanted to be really fancy we could use Blur Behind:
@ -79,7 +85,7 @@ MainWindow::MainWindow(QWidget *parent) :
PacketList *packetList = new PacketList(splitterV);
QTreeWidget *protoTree = new QTreeWidget(splitterV);
ProtoTree *protoTree = new ProtoTree(splitterV);
protoTree->setHeaderHidden(true);
ByteViewTab *byteViewTab = new ByteViewTab(splitterV);
@ -97,7 +103,22 @@ MainWindow::MainWindow(QWidget *parent) :
mainWelcome = new MainWelcome(ui->mainStack);
ui->mainStack->addWidget(mainWelcome);
connect(mainWelcome, SIGNAL(recentFileActivated(QString&)), this, SLOT(openCaptureFile(QString&)));
connect(mainWelcome, SIGNAL(recentFileActivated(QString&)),
this, SLOT(openCaptureFile(QString&)));
connect(wsApp, SIGNAL(captureFileReadStarted(const capture_file*)),
this, SLOT(captureFileReadStarted(const capture_file*)));
connect(wsApp, SIGNAL(captureFileReadFinished(const capture_file*)),
this, SLOT(captureFileReadFinished(const capture_file*)));
connect(wsApp, SIGNAL(captureFileClosing(const capture_file*)),
this, SLOT(captureFileClosing(const capture_file*)));
connect(wsApp, SIGNAL(captureFileClosed(const capture_file*)),
this, SLOT(captureFileClosed(const capture_file*)));
connect(protoTree, SIGNAL(protoItemSelected(QString&)),
ui->statusBar, SLOT(pushFieldStatus(QString&)));
connect(protoTree, SIGNAL(protoItemUnselected()),
ui->statusBar, SLOT(popFieldStatus()));
ui->mainStack->setCurrentWidget(mainWelcome);
}
@ -107,6 +128,72 @@ MainWindow::~MainWindow()
delete ui;
}
void MainWindow::keyPressEvent(QKeyEvent *event) {
if (event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_Slash) {
dfComboBox->setFocus(Qt::ShortcutFocusReason);
return;
}
QMainWindow::keyPressEvent(event);
}
void MainWindow::captureFileReadStarted(const capture_file *cf) {
if (cf != capFile) return;
// tap_param_dlg_update();
/* Set up main window for a capture file. */
// main_set_for_capture_file(TRUE);
ui->statusBar->popFileStatus();
QString msg = QString().sprintf("Loading: %s", get_basename(cf->filename));
ui->statusBar->pushFileStatus(msg);
}
void MainWindow::captureFileReadFinished(const capture_file *cf) {
if (cf != capFile) return;
// gchar *dir_path;
// if (!cf->is_tempfile && cf->filename) {
// /* Add this filename to the list of recent files in the "Recent Files" submenu */
// add_menu_recent_capture_file(cf->filename);
// /* Remember folder for next Open dialog and save it in recent */
// dir_path = get_dirname(g_strdup(cf->filename));
// set_last_open_dir(dir_path);
// g_free(dir_path);
// }
// set_display_filename(cf);
// /* Enable menu items that make sense if you have a capture file you've
// finished reading. */
// set_menus_for_capture_file(cf);
// /* Enable menu items that make sense if you have some captured packets. */
// set_menus_for_captured_packets(TRUE);
ui->statusBar->popFileStatus();
QString msg = QString().sprintf("%s", get_basename(cf->filename));
ui->statusBar->pushFileStatus(msg);
}
void MainWindow::captureFileClosing(const capture_file *cf) {
if (cf != capFile) return;
/* reset expert info indicator */
// status_expert_hide();
// gtk_widget_show(expert_info_none);
}
void MainWindow::captureFileClosed(const capture_file *cf) {
if (cf != capFile) return;
packets_bar_update();
ui->statusBar->popFileStatus();
capFile = NULL;
}
void MainWindow::closeCaptureFile() {
cf_close(&cfile);
ui->mainStack->setCurrentWidget(mainWelcome);
@ -144,9 +231,11 @@ void MainWindow::openCaptureFile(QString &cfPath)
try again. */
if (rfcode != NULL)
dfilter_free(rfcode);
capFile = NULL;
return;
} else {
ui->mainStack->setCurrentWidget(splitterV);
capFile = &cfile;
cf_read(&cfile, FALSE);
}
}
@ -217,13 +306,3 @@ void MainWindow::updateRecentFiles() {
}
}
}
void MainWindow::keyPressEvent(QKeyEvent *event) {
if (event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_Slash) {
dfComboBox->setFocus(Qt::ShortcutFocusReason);
return;
}
QMainWindow::keyPressEvent(event);
}

View File

@ -26,6 +26,12 @@
#include <stdio.h>
#include "config.h"
#include <glib.h>
#include "file.h"
#include <QMainWindow>
#include <QSplitter>
#include "main_welcome.h"
@ -54,8 +60,13 @@ private:
QSplitter *splitterV;
MainWelcome *mainWelcome;
DisplayFilterCombo *dfComboBox;
capture_file *capFile;
public slots:
void captureFileReadStarted(const capture_file *cf);
void captureFileReadFinished(const capture_file *cf);
void captureFileClosing(const capture_file *cf);
void captureFileClosed(const capture_file *cf);
private slots:
void closeCaptureFile();

View File

@ -115,7 +115,7 @@
<addaction name="actionStopCapture"/>
<addaction name="separator"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<widget class="MainStatusBar" name="statusBar"/>
<widget class="QToolBar" name="utilityToolBar">
<property name="windowTitle">
<string>toolBar</string>
@ -197,6 +197,13 @@
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MainStatusBar</class>
<extends>QStatusBar</extends>
<header>main_status_bar.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="toolbar.qrc"/>
</resources>

View File

@ -41,6 +41,7 @@
#include "ui_util.h"
#include "globals.h"
#include "qt_ui_utils.h"
#include "main_statusbar.h"
#include "gtk/recent.h"
@ -56,8 +57,11 @@ static gboolean enable_color;
static PacketList *cur_packet_list = NULL;
guint
new_packet_list_append(column_info *cinfo _U_, frame_data *fdata, packet_info *pinfo _U_)
new_packet_list_append(column_info *cinfo, frame_data *fdata, packet_info *pinfo)
{
Q_UNUSED(cinfo);
Q_UNUSED(pinfo);
if (!cur_packet_list)
return 0;
@ -200,7 +204,7 @@ new_packet_list_thaw(void)
// /* Remove extra reference added by new_packet_list_freeze() */
// g_object_unref(packetlist);
// packets_bar_update();
packets_bar_update();
}
void
@ -288,7 +292,7 @@ PacketList::PacketList(QWidget *parent) :
m_byteViewTab = NULL;
}
void PacketList::setProtoTree (QTreeWidget *protoTree) {
void PacketList::setProtoTree (ProtoTree *protoTree) {
m_protoTree = protoTree;
}
@ -301,6 +305,7 @@ PacketListModel *PacketList::packetListModel() const {
}
void PacketList::showEvent (QShowEvent *event) {
Q_UNUSED(event);
// g_log(NULL, G_LOG_LEVEL_DEBUG, "cols: %d", cfile.cinfo.num_cols);
for (int i = 0; i < cfile.cinfo.num_cols; i++) {
int fmt, col_width;
@ -321,8 +326,6 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
QTreeView::selectionChanged(selected, deselected);
if (m_protoTree) {
// Connect signals between the proto tree and byte views.
int row = selected.first().top();
cf_select_packet(&cfile, row);
@ -330,10 +333,9 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
return;
}
proto_tree_draw(cfile.edt->tree, m_protoTree);
m_protoTree->fillProtocolTree(cfile.edt->tree);
}
g_log(NULL, G_LOG_LEVEL_DEBUG, "bvt: %p", m_byteViewTab);
if (m_byteViewTab && cfile.edt) {
GSList *src_le;
data_source *source;
@ -350,6 +352,7 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
}
if (m_protoTree && m_byteViewTab) {
// Connect signals between the proto tree and byte views.
connect(m_protoTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
m_byteViewTab, SLOT(protoTreeItemChanged(QTreeWidgetItem*)));
}
@ -369,7 +372,6 @@ void PacketList::clear() {
// * Reset the sort column, use packetlist as model in case the list is frozen.
// */
cur_packet_list->sortByColumn(0, Qt::AscendingOrder);
}
void new_packet_list_recent_write_all(FILE *rf) {

View File

@ -25,6 +25,7 @@
#define PACKET_LIST_H
#include "packet_list_model.h"
#include "proto_tree.h"
#include "byte_view_tab.h"
#include <QTreeView>
@ -37,7 +38,7 @@ class PacketList : public QTreeView
public:
explicit PacketList(QWidget *parent = 0);
PacketListModel *packetListModel() const;
void setProtoTree(QTreeWidget *protoTree);
void setProtoTree(ProtoTree *protoTree);
void setByteViewTab(ByteViewTab *byteViewTab);
void clear();
void writeRecent(FILE *rf);
@ -48,7 +49,7 @@ protected:
private:
PacketListModel *m_packet_list_model;
QTreeWidget *m_protoTree;
ProtoTree *m_protoTree;
ByteViewTab *m_byteViewTab;
signals:

View File

@ -21,6 +21,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include "proto_tree.h"
#include "monospace_font.h"
@ -36,17 +38,6 @@ QColor expert_color_error ( 0xff, 0x5c, 0x5c ); /* pale red *
QColor expert_color_foreground ( 0x00, 0x00, 0x00 ); /* black */
QColor hidden_proto_item ( 0x44, 0x44, 0x44 ); /* gray */
static void
proto_tree_draw_node(proto_node *node, gpointer data);
void proto_tree_draw(proto_tree *protocol_tree, QTreeWidget *protoTree) {
// Clear out previous tree
protoTree->clear();
protoTree->setFont(get_monospace_font());
proto_tree_children_foreach(protocol_tree, proto_tree_draw_node, protoTree->invisibleRootItem());
}
/* Fill a single protocol tree item with its string value and set its color. */
static void
proto_tree_draw_node(proto_node *node, gpointer data)
@ -152,4 +143,76 @@ ProtoTree::ProtoTree(QWidget *parent) :
QTreeWidget(parent)
{
setAccessibleName("Packet details");
setFont(get_monospace_font());
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
this, SLOT(updateSelectionStatus(QTreeWidgetItem*)));
}
void ProtoTree::clear() {
updateSelectionStatus(NULL);
QTreeWidget::clear();
}
void ProtoTree::fillProtocolTree(proto_tree *protocol_tree) {
// Clear out previous tree
clear();
proto_tree_children_foreach(protocol_tree, proto_tree_draw_node, invisibleRootItem());
}
void ProtoTree::updateSelectionStatus(QTreeWidgetItem* item) {
if (item) {
field_info *fi;
QVariant v;
QString itemInfo;
int finfo_length;
v = item->data(0, Qt::UserRole);
fi = (field_info *) v.value<void *>();
if (!fi || !fi->hfinfo) return;
if (fi->hfinfo->blurb != NULL && fi->hfinfo->blurb[0] != '\0') {
itemInfo.append(QString().fromUtf8(fi->hfinfo->blurb));
} else {
itemInfo.append(QString().fromUtf8(fi->hfinfo->name));
}
if (!itemInfo.isEmpty()) {
itemInfo.append(" (" + QString().fromUtf8(fi->hfinfo->abbrev) + ")");
finfo_length = fi->length + fi->appendix_length;
if (finfo_length == 1) {
itemInfo.append(", 1 byte");
} else if (finfo_length > 1) {
itemInfo.append(QString(", %1 bytes").arg(finfo_length));
}
emit protoItemUnselected();
emit protoItemSelected(itemInfo);
} // else the GTK+ version pushes an empty string as described below.
/*
* Don't show anything if the field name is zero-length;
* the pseudo-field for "proto_tree_add_text()" is such
* a field, and we don't want "Text (text)" showing up
* on the status line if you've selected such a field.
*
* XXX - there are zero-length fields for which we *do*
* want to show the field name.
*
* XXX - perhaps the name and abbrev field should be null
* pointers rather than null strings for that pseudo-field,
* but we'd have to add checks for null pointers in some
* places if we did that.
*
* Or perhaps protocol tree items added with
* "proto_tree_add_text()" should have -1 as the field index,
* with no pseudo-field being used, but that might also
* require special checks for -1 to be added.
*/
} else {
emit protoItemUnselected();
}
}

View File

@ -30,17 +30,23 @@
#include <QTreeWidget>
void proto_tree_draw(proto_tree *protocol_tree, QTreeWidget *protoTree);
class ProtoTree : public QTreeWidget
{
Q_OBJECT
public:
explicit ProtoTree(QWidget *parent = 0);
void fillProtocolTree(proto_tree *protocol_tree);
void clear();
private:
signals:
void protoItemSelected(QString &);
void protoItemUnselected();
public slots:
void updateSelectionStatus(QTreeWidgetItem*);
};

View File

@ -31,6 +31,8 @@
#include "qt_ui_utils.h"
#include "file.h"
#include "log.h"
#include "recent_file_status.h"
#include <QDir>
@ -176,6 +178,55 @@ void WiresharkApplication::refreshRecentFiles(void) {
}
}
void WiresharkApplication::captureFileCallback(int event, void * data)
{
capture_file *cf = (capture_file *) data;
switch(event) {
case(cf_cb_file_closing):
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
emit captureFileClosing(cf);
break;
case(cf_cb_file_closed):
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
emit captureFileClosed(cf);
break;
case(cf_cb_file_read_started):
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
emit captureFileReadStarted(cf);
break;
case(cf_cb_file_read_finished):
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
emit captureFileReadFinished(cf);
break;
case(cf_cb_packet_selected):
case(cf_cb_packet_unselected):
case(cf_cb_field_unselected):
// Pure signals and slots
break;
// case(cf_cb_file_save_started): // data = string
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
// break;
// case(cf_cb_file_save_finished):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
// break;
// case(cf_cb_file_save_reload_finished):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
// main_cf_cb_file_save_reload_finished(data);
// break;
// case(cf_cb_file_save_failed):
// g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
// break;
default:
g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: main_cf_callback %d %p", event, data);
// g_warning("main_cf_callback: event %u unknown", event);
// g_assert_not_reached();
}
}
void WiresharkApplication::clearRecentItems() {
recent_item_status *ri;

View File

@ -24,6 +24,12 @@
#ifndef WIRESHARK_APPLICATION_H
#define WIRESHARK_APPLICATION_H
#include "config.h"
#include <glib.h>
#include "file.h"
#include <QApplication>
#include <QList>
#include <QFileInfo>
@ -49,6 +55,7 @@ public:
explicit WiresharkApplication(int &argc, char **argv);
QList<recent_item_status *> recent_item_list() const;
void addRecentItem(const QString &filename, qint64 size, bool accessible);
void captureFileCallback(int event, void * data);
private:
QTimer *recentTimer;
@ -56,6 +63,11 @@ private:
signals:
void updateRecentItemStatus(const QString &filename, qint64 size, bool accessible);
void captureFileReadStarted(const capture_file *cf);
void captureFileReadFinished(const capture_file *cf);
void captureFileClosing(const capture_file *cf);
void captureFileClosed(const capture_file *cf);
public slots:
void clearRecentItems();