diff --git a/fileset.c b/fileset.c index 4112fdb75d..66f28a6a0b 100644 --- a/fileset.c +++ b/fileset.c @@ -125,7 +125,7 @@ fileset_filename_match_pattern(const char *fname) /* test, if both files could be in the same file set */ /* (the filenames must already be in correct shape) */ -gboolean +static gboolean fileset_is_file_in_set(const char *fname1, const char *fname2) { char *pfx1; diff --git a/fileset.h b/fileset.h index adf1ca6dd5..597455a9c0 100644 --- a/fileset.h +++ b/fileset.h @@ -43,9 +43,6 @@ typedef struct _fileset_entry { /* helper: is this a probable file of a file set (does the naming pattern match)? */ extern gboolean fileset_filename_match_pattern(const char *fname); -/* helper: test, if both files could be in the same file set */ -extern gboolean fileset_is_file_in_set(const char *fname1, const char *fname2); - extern void fileset_add_dir(const char *fname, void *window); extern void fileset_delete(void); diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index 0449494999..a047caeedb 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -33,7 +33,7 @@ set(QTSHARK_H_SRC color_utils.h display_filter_combo.h display_filter_edit.h - fileset_dialog.h + file_set_dialog.h import_text_dialog.h interface_tree.h label_stack.h @@ -64,7 +64,7 @@ set(QTSHARK_CPP_SRC color_utils.cpp display_filter_combo.cpp display_filter_edit.cpp - fileset_dialog.cpp + file_set_dialog.cpp import_text_dialog.cpp interface_tree.cpp label_stack.cpp diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index c967c3214d..3761df4827 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -76,7 +76,7 @@ MOC_HDRS = \ color_utils.h \ display_filter_combo.h \ display_filter_edit.h \ - fileset_dialog.h \ + file_set_dialog.h \ interface_tree.h \ label_stack.h \ main_status_bar.h \ @@ -129,7 +129,7 @@ WIRESHARK_QT_SRC = \ color_utils.cpp \ display_filter_combo.cpp \ display_filter_edit.cpp \ - fileset_dialog.cpp \ + file_set_dialog.cpp \ interface_tree.cpp \ label_stack.cpp \ main_status_bar.cpp \ diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro index eb1d6776c6..f7a667ce92 100644 --- a/ui/qt/QtShark.pro +++ b/ui/qt/QtShark.pro @@ -183,7 +183,7 @@ SOURCES_QT_CPP = \ color_utils.cpp \ display_filter_combo.cpp \ display_filter_edit.cpp \ - fileset_dialog.cpp \ + file_set_dialog.cpp \ interface_tree.cpp \ label_stack.cpp \ main.cpp \ @@ -216,7 +216,7 @@ HEADERS_QT_CPP = \ color_utils.h \ display_filter_combo.h \ display_filter_edit.h \ - fileset_dialog.h \ + file_set_dialog.h \ interface_tree.h \ label_stack.h \ main_status_bar.h \ @@ -237,7 +237,8 @@ HEADERS_QT_CPP = \ FORMS += main_window.ui \ main_welcome.ui \ - import_text_dialog.ui + import_text_dialog.ui \ + file_set_dialog.ui win32 { ## These should be in config.pri ?? !isEmpty(PORTAUDIO_DIR) { diff --git a/ui/qt/file_set_dialog.cpp b/ui/qt/file_set_dialog.cpp new file mode 100644 index 0000000000..99bfdc9caf --- /dev/null +++ b/ui/qt/file_set_dialog.cpp @@ -0,0 +1,225 @@ +/* fileset_dialog.cpp + * + * $Id: fileset_dialog.cpp 45017 2012-09-20 02:03:38Z morriss $ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 "config.h" + +#include + +#include "file.h" +#include "fileset.h" + +#include "ui/help_url.h" + +#include "file_set_dialog.h" +#include "ui_file_set_dialog.h" + +#include +#include +#include +#include +#include +#include +#include + + +Q_DECLARE_METATYPE(fileset_entry *) + +/* this file is a part of the current file set, add it to the dialog */ +void +fileset_dlg_add_file(fileset_entry *entry, void *window) { + FileSetDialog *fs_dlg = static_cast(window); + + if (fs_dlg) fs_dlg->addFile(entry); +} + +FileSetDialog::FileSetDialog(QWidget *parent) : + QDialog(parent), + fs_ui_(new Ui::FileSetDialog), + close_button_(NULL) +{ + QTreeWidgetItem *header; + + fs_ui_->setupUi(this); + + header = fs_ui_->fileSetTree->headerItem(); + header->setText(0, "Filename"); + header->setText(1, "Created"); + header->setText(2, "Modified"); + header->setText(3, "Size"); + + close_button_ = fs_ui_->buttonBox->button(QDialogButtonBox::Close); + addFile(); +} + +FileSetDialog::~FileSetDialog() +{ + delete fs_ui_; +} + +/* a new capture file was opened, browse the dir and look for files matching the given file set */ +void FileSetDialog::fileOpened(const capture_file *cf) { + if (!cf) return; + fs_ui_->fileSetTree->clear(); +// fileset_delete(); + fileset_add_dir(cf->filename, this); +// if(fs_w) { +// window_present(fs_w); +// } + +} + +/* the capture file was closed */ +void FileSetDialog::fileClosed() { + fileset_delete(); + fs_ui_->fileSetTree->clear(); + +// if(fs_w) { +// /* reinit the table, title and alike */ +// g_object_ref(G_OBJECT(fs_tb_vb)); +// gtk_widget_destroy(fs_tb); +// fileset_delete(); +// fileset_init_table(fs_tb_vb); +// window_present(fs_w); +// } else { +// fileset_delete(); +// } + +} + +void FileSetDialog::addFile(fileset_entry *entry) { + QString created; + QString modified; + QString size; + QString dir_name; + QString elided_dir_name; + QTreeWidgetItem *entry_item; + + if (!entry) { + setWindowTitle("Wireshark: No files in Set"); + fs_ui_->directoryLabel->setText("No capture loaded"); + fs_ui_->directoryLabel->setEnabled(false); + return; + } + + created = nameToDate(entry->name); + if(created.length() < 1) { + /* if this file doesn't follow the file set pattern, */ + /* use the creation time of that file */ + /* http://en.wikipedia.org/wiki/ISO_8601 */ + created = QDateTime::fromTime_t(entry->ctime).toLocalTime().toString("yyyy-MM-dd HH:mm:ss"); + } + + modified = QDateTime::fromTime_t(entry->mtime).toLocalTime().toString("yyyy-MM-dd HH:mm:ss"); + + size = QString("%1 Bytes").arg(entry->size); + + entry_item = new QTreeWidgetItem(fs_ui_->fileSetTree); + entry_item->setToolTip(0, QString("Open this capture file")); + entry_item->setData(0, Qt::UserRole, qVariantFromValue(entry)); + + entry_item->setText(0, entry->name); + entry_item->setText(1, created); + entry_item->setText(2, modified); + entry_item->setText(3, size); + + setWindowTitle(QString("Wireshark: %1 File%2 in Set") + .arg(fs_ui_->fileSetTree->topLevelItemCount()) + .arg(plurality(fs_ui_->fileSetTree->topLevelItemCount(), "", "s"))); + + dir_name = fileset_get_dirname(); + elided_dir_name = fs_ui_->directoryLabel->fontMetrics().elidedText(dir_name, Qt::ElideLeft, fs_ui_->directoryLabel->maximumWidth()); + fs_ui_->directoryLabel->setText(QString("%2").arg(dir_name).arg(elided_dir_name)); + fs_ui_->directoryLabel->setEnabled(true); + + if(entry->current) { + fs_ui_->fileSetTree->setCurrentItem(entry_item); + } + + if (close_button_) + close_button_->setEnabled(true); + + fs_ui_->fileSetTree->addTopLevelItem(entry_item); + for (int i = 0; i < 4; i++) + fs_ui_->fileSetTree->resizeColumnToContents(i); + fs_ui_->fileSetTree->setFocus(); +} + +QString FileSetDialog::nameToDate(const char *name) { + QString dn; + + if (!fileset_filename_match_pattern(name)) + return NULL; + + dn = name; + dn.remove(QRegExp(".*_")); + dn.truncate(14); + dn.insert(4, '-'); + dn.insert(7, '-'); + dn.insert(10, ' '); + dn.insert(13, ':'); + dn.insert(16, ':'); + return dn; +} + +void FileSetDialog::on_buttonBox_helpRequested() +{ + gchar *url = topic_action_url(HELP_FILESET_DIALOG); + + if(url != NULL) { + QDesktopServices::openUrl(QUrl(url)); + g_free(url); + } +} + +void FileSetDialog::on_fileSetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + Q_UNUSED(previous); + + fileset_entry *entry; + + if (!current) + return; + + entry = current->data(0, Qt::UserRole).value(); + + if (!entry || entry->current) + return; + + QString new_cf_path = entry->fullname; + + if (new_cf_path.length() > 0) + emit fileSetOpenCaptureFile(new_cf_path); +} + +/* + * 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: + */ diff --git a/ui/qt/fileset_dialog.h b/ui/qt/file_set_dialog.h similarity index 57% rename from ui/qt/fileset_dialog.h rename to ui/qt/file_set_dialog.h index c6ae13f59f..275b9bf6f7 100644 --- a/ui/qt/fileset_dialog.h +++ b/ui/qt/file_set_dialog.h @@ -1,6 +1,6 @@ /* fileset_dialog.h * - * $Id$ + * $Id: fileset_dialog.h 44766 2012-09-04 08:18:31Z alagoutte $ * * Wireshark - Network traffic analyzer * By Gerald Combs @@ -21,24 +21,51 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef FILESET_DIALOG_H -#define FILESET_DIALOG_H +#ifndef FILE_SET_DIALOG_H +#define FILE_SET_DIALOG_H + +#include "config.h" + +#include + +#include "file.h" +#include "fileset.h" #include +#include -class FilesetDialog : public QDialog +namespace Ui { +class FileSetDialog; +} + +class FileSetDialog : public QDialog { Q_OBJECT + public: - explicit FilesetDialog(QWidget *parent = 0); + explicit FileSetDialog(QWidget *parent = 0); + ~FileSetDialog(); + + void fileOpened(const capture_file *cf); + void fileClosed(); + void addFile(fileset_entry *entry = NULL); signals: + void fileSetOpenCaptureFile(QString &); -public slots: +private slots: + void on_buttonBox_helpRequested(); + void on_fileSetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + +private: + QString nameToDate(const char *name); + + Ui::FileSetDialog *fs_ui_; + QPushButton *close_button_; }; -#endif // FILESET_DIALOG_H +#endif // FILE_SET_DIALOG_H /* * Editor modelines diff --git a/ui/qt/file_set_dialog.ui b/ui/qt/file_set_dialog.ui new file mode 100644 index 0000000000..d78afd1c74 --- /dev/null +++ b/ui/qt/file_set_dialog.ui @@ -0,0 +1,140 @@ + + + FileSetDialog + + + + 0 + 0 + 750 + 450 + + + + Dialog + + + true + + + + + + QFormLayout::FieldsStayAtSizeHint + + + + + + + Directory: + + + + + + + + 1 + 0 + + + + + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::Help + + + + + + + + 0 + 1 + + + + Qt::ElideLeft + + + 4 + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + + + + + + + + buttonBox + accepted() + FileSetDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + FileSetDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/ui/qt/fileset_dialog.cpp b/ui/qt/fileset_dialog.cpp deleted file mode 100644 index 1e4ba05b04..0000000000 --- a/ui/qt/fileset_dialog.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* fileset_dialog.cpp - * - * $Id$ - * - * Wireshark - Network traffic analyzer - * By Gerald Combs - * 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 "config.h" - -#include - -#include "fileset_dialog.h" - -#include "fileset.h" - -/* this file is a part of the current file set, add it to the dialog */ -void -fileset_dlg_add_file(fileset_entry *entry) { -// char *created; -// char *modified; -// char *size; -// struct tm *local; -// GtkWidget *fs_lb; -// GtkWidget *fs_rb; -// gchar *title; - - - g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fileset_dlg_add_file: %s", entry->name); -// if (fs_w == NULL) { -// return; -// } - -// created = fileset_dlg_name2date_dup(entry->name); -// if(!created) { -// /* if this file doesn't follow the file set pattern, */ -// /* use the creation time of that file */ -// local = localtime(&entry->ctime); -// created = g_strdup_printf("%04u.%02u.%02u %02u:%02u:%02u", -// local->tm_year+1900, local->tm_mon+1, local->tm_mday, -// local->tm_hour, local->tm_min, local->tm_sec); -// } - -// local = localtime(&entry->mtime); -// modified = g_strdup_printf("%04u.%02u.%02u %02u:%02u:%02u", -// local->tm_year+1900, local->tm_mon+1, local->tm_mday, -// local->tm_hour, local->tm_min, local->tm_sec); -// size = g_strdup_printf("%" G_GINT64_MODIFIER "d Bytes", entry->size); - -// fs_rb = gtk_radio_button_new_with_label_from_widget( -// fs_first_rb ? GTK_RADIO_BUTTON(fs_first_rb) : NULL, entry->name); -// if(row == 1) { -// fs_first_rb = fs_rb; -// } -// if(entry->current) { -// gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (fs_rb), entry->current); -// } -// gtk_tooltips_set_tip(tooltips, fs_rb, "Open this capture file", NULL); -// gtk_table_attach_defaults(GTK_TABLE(fs_tb), fs_rb, 0, 1, row, row+1); -// g_signal_connect(fs_rb, "toggled", G_CALLBACK(fs_rb_cb), entry); -// gtk_widget_show(fs_rb); - -// fs_lb = gtk_label_new(created); -// gtk_table_attach_defaults(GTK_TABLE(fs_tb), fs_lb, 1, 2, row, row+1); -// gtk_widget_set_sensitive(fs_lb, entry->current); -// gtk_widget_show(fs_lb); - -// fs_lb = gtk_label_new(modified); -// gtk_table_attach_defaults(GTK_TABLE(fs_tb), fs_lb, 2, 3, row, row+1); -// gtk_widget_set_sensitive(fs_lb, entry->current); -// gtk_widget_show(fs_lb); - -// fs_lb = gtk_label_new(size); -// gtk_table_attach_defaults(GTK_TABLE(fs_tb), fs_lb, 3, 4, row, row+1); -// gtk_widget_set_sensitive(fs_lb, entry->current); -// gtk_widget_show(fs_lb); - -// title = g_strdup_printf("Wireshark: %u File%s in Set", row, plurality(row, "", "s")); -// gtk_window_set_title(GTK_WINDOW(fs_w), title); -// g_free(title); - -// title = g_strdup_printf("... in directory: %s", fileset_get_dirname()); -// gtk_label_set_text(GTK_LABEL(fs_dir_lb), title); -// g_free(title); - -// gtk_widget_show_all(fs_tb); - -// /* resize the table until we use 18 rows (fits well into 800*600), if it's bigger use a scrollbar */ -// /* XXX - I didn't found a way to automatically shrink the table size again */ -// if(row <= 18) { -// GtkRequisition requisition; - -// gtk_widget_size_request(fs_tb, &requisition); -// gtk_widget_set_size_request(fs_sw, -1, requisition.height); -// gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fs_sw), GTK_POLICY_NEVER, GTK_POLICY_NEVER); -// } - -// if(row == 18) { -// gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fs_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); -// } - -// row++; - -// g_free(created); -// g_free(modified); -// g_free(size); -} - -/* a new capture file was opened, browse the dir and look for files matching the given file set */ -void -fileset_file_opened(const char *fname) { - g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fileset_file_opened: %s", fname); -// fileset_add_dir(fname); -// if(fs_w) { -// window_present(fs_w); -// } - -// /* update the menu */ -// set_menus_for_file_set(TRUE /* file_set */, -// fileset_get_previous() != NULL, fileset_get_next() != NULL ); -} - - -/* the capture file was closed */ -void -fileset_file_closed(void) -{ - g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fileset_file_closed"); -// if(fs_w) { -// /* reinit the table, title and alike */ -// g_object_ref(G_OBJECT(fs_tb_vb)); -// gtk_widget_destroy(fs_tb); -// fileset_delete(); -// fileset_init_table(fs_tb_vb); -// window_present(fs_w); -// } else { -// fileset_delete(); -// } - -// /* update the menu */ -// set_menus_for_file_set(FALSE /* file_set */, -// fileset_get_previous() != NULL, -// fileset_get_next() != NULL ); -} - -FilesetDialog::FilesetDialog(QWidget *parent) : - QDialog(parent) -{ -} - -/* - * 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: - */ diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index 1a063b5657..d08cbd1873 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -107,6 +107,7 @@ MainWindow::MainWindow(QWidget *parent) : main_ui_->setupUi(this); setMenusForCaptureFile(); setForCaptureInProgress(false); + setMenusForFileSet(false); connect(wsApp, SIGNAL(updateRecentItemStatus(const QString &, qint64, bool)), this, SLOT(updateRecentFiles())); updateRecentFiles(); @@ -196,6 +197,8 @@ MainWindow::MainWindow(QWidget *parent) : this, SLOT(captureCaptureFailed(capture_options *))); #endif + connect(wsApp, SIGNAL(captureFileOpened(const capture_file*)), + this, SLOT(captureFileOpened(const capture_file*))); connect(wsApp, SIGNAL(captureFileReadStarted(const capture_file*)), this, SLOT(captureFileReadStarted(const capture_file*))); connect(wsApp, SIGNAL(captureFileReadFinished(const capture_file*)), @@ -206,7 +209,7 @@ MainWindow::MainWindow(QWidget *parent) : this, SLOT(captureFileClosed(const capture_file*))); connect(main_welcome_, SIGNAL(recentFileActivated(QString&)), - this, SLOT(openRecentCaptureFile(QString&))); + this, SLOT(openCaptureFile(QString&))); connect(main_ui_->actionGoNextPacket, SIGNAL(triggered()), packet_list_, SLOT(goNextPacket())); @@ -230,6 +233,9 @@ MainWindow::MainWindow(QWidget *parent) : connect(proto_tree, SIGNAL(protoItemSelected(bool)), main_ui_->actionViewExpandSubtrees, SLOT(setEnabled(bool))); + connect(&file_set_dialog_, SIGNAL(fileSetOpenCaptureFile(QString&)), + this, SLOT(openCaptureFile(QString&))); + main_ui_->mainStack->setCurrentWidget(main_welcome_); } @@ -339,9 +345,7 @@ void MainWindow::openCaptureFile(QString &cf_path) dfilter_t *rfcode = NULL; int err; - cap_file_ = NULL; - - testCaptureFileClose(&cfile, false); + testCaptureFileClose(false); for (;;) { @@ -390,19 +394,19 @@ void MainWindow::openCaptureFile(QString &cf_path) } /* Try to open the capture file. */ + cfile.window = this; if (cf_open(&cfile, cf_path.toUtf8().constData(), FALSE, &err) != CF_OK) { /* We couldn't open it; don't dismiss the open dialog box, just leave it around so that the user can, after they dismiss the alert box popped up for the open error, try again. */ + cfile.window = NULL; if (rfcode != NULL) dfilter_free(rfcode); cf_path.clear(); continue; } - cfile.window = this; - switch (cf_read(&cfile, FALSE)) { case CF_READ_OK: @@ -604,7 +608,7 @@ void MainWindow::mergeCaptureFile() void MainWindow::importCaptureFile() { ImportTextDialog import_dlg; - if (!testCaptureFileClose(cap_file_, FALSE, *new QString(" before importing a new capture"))) + if (!testCaptureFileClose(FALSE, *new QString(" before importing a new capture"))) return; import_dlg.exec(); @@ -844,7 +848,7 @@ void MainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_comments, //#endif /* Attempt to save the file */ - status = cf_save_packets(&cfile, file_name.toUtf8().constData(), file_type, compressed, + status = cf_save_packets(cf, file_name.toUtf8().constData(), file_type, compressed, discard_comments, stay_closed); switch (status) { @@ -871,14 +875,14 @@ void MainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_comments, return; } -bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString &before_what) { +bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) { bool capture_in_progress = FALSE; - if (!cf || cf->state == FILE_CLOSED) + if (!cap_file_ || cap_file_->state == FILE_CLOSED) return true; /* Already closed, nothing to do */ #ifdef HAVE_LIBPCAP - if (cf->state == FILE_READ_IN_PROGRESS) { + if (cap_file_->state == FILE_READ_IN_PROGRESS) { /* This is true if we're reading a capture file *or* if we're doing a live capture. If we're reading a capture file, the main loop is busy reading packets, and only accepting input from the @@ -889,7 +893,7 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString #endif if (prefs.gui_ask_unsaved) { - if (cf->is_tempfile || capture_in_progress || cf->unsaved_changes) { + if (cap_file_->is_tempfile || capture_in_progress || cap_file_->unsaved_changes) { QMessageBox msg_dialog; QString question; QPushButton *default_button; @@ -900,7 +904,7 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString /* This is a temporary capture file, or there's a capture in progress, or the file has unsaved changes; ask the user whether to save the data. */ - if (cf->is_tempfile) { + if (cap_file_->is_tempfile) { msg_dialog.setText("You have unsaved packets"); msg_dialog.setInformativeText("They will be lost if you don't save them."); @@ -923,7 +927,7 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString question.append(before_what).append("?"); msg_dialog.setInformativeText("Your captured packets will be lost if you don't save them."); } else { - gchar *display_basename = g_filename_display_basename(cf->filename); + gchar *display_basename = g_filename_display_basename(cap_file_->filename); question.append(QString("Do you want to save the changes you've made to the capture file \"%1\"%2?") .arg(display_basename) .arg(before_what) @@ -948,7 +952,7 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString msg_dialog.setDefaultButton(default_button); if (from_quit) { - if (cf->state == FILE_READ_IN_PROGRESS) { + if (cap_file_->state == FILE_READ_IN_PROGRESS) { msg_dialog.addButton("Stop and Quit without Saving", QMessageBox::DestructiveRole); } else { msg_dialog.addButton("Quit without Saving", QMessageBox::DestructiveRole); @@ -970,10 +974,10 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString /* If there's a capture in progress, we have to stop the capture and then do the save. */ if (capture_in_progress) - captureStop(cf); + captureStop(); #endif /* Save the file and close it */ - saveCaptureFile(cf, TRUE); + saveCaptureFile(cap_file_, TRUE); break; case QMessageBox::Discard: @@ -983,10 +987,10 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString * and then do the close. */ if (capture_in_progress) - captureStop(cf); + captureStop(); #endif /* Just close the file, discarding changes */ - cf_close(cf); + cf_close(cap_file_); return true; break; @@ -998,7 +1002,7 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString } } else { /* Unchanged file, just close it */ - cf_close(cf); + cf_close(cap_file_); } } else { /* User asked not to be bothered by those prompts, just close it. @@ -1007,18 +1011,18 @@ bool MainWindow::testCaptureFileClose(capture_file *cf, bool from_quit, QString /* If there's a capture in progress, we have to stop the capture and then do the close. */ if (capture_in_progress) - captureStop(cf); + captureStop(); #endif - cf_close(cf); + cf_close(cap_file_); } return true; /* File closed */ } -void MainWindow::captureStop(capture_file *cf) { +void MainWindow::captureStop() { stopCapture(); - while(cf->state == FILE_READ_IN_PROGRESS) { + while(cap_file_ && cap_file_->state == FILE_READ_IN_PROGRESS) { WiresharkApplication::processEvents(); } } @@ -1097,7 +1101,7 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) { main_ui_->actionFileExportPacketBytes->setEnabled(capture_in_progress); main_ui_->actionFileExportSSLSessionKeys->setEnabled(capture_in_progress); main_ui_->actionFileExportObjects->setEnabled(capture_in_progress); - main_ui_->menuFile_Set->setEnabled(capture_in_progress); + main_ui_->menuFileSet->setEnabled(!capture_in_progress); main_ui_->actionFileQuit->setEnabled(true); // set_menu_sensitivity(ui_manager_packet_list_heading, "/PacketListHeadingPopup/SortAscending", @@ -1126,6 +1130,15 @@ void MainWindow::setMenusForCaptureStopping() { #endif /* HAVE_LIBPCAP */ } +void MainWindow::setMenusForFileSet(bool enable_list_files) { + bool enable_next = fileset_get_next() != NULL && enable_list_files; + bool enable_prev = fileset_get_previous() != NULL && enable_list_files; + + main_ui_->actionFileSetListFiles->setEnabled(enable_list_files); + main_ui_->actionFileSetNextFile->setEnabled(enable_next); + main_ui_->actionFileSetPreviousFile->setEnabled(enable_prev); +} + void MainWindow::updateForUnsavedChanges() { // set_display_filename(cf); setMenusForCaptureFile(); @@ -1222,8 +1235,16 @@ void MainWindow::captureCaptureFailed(capture_options *capture_opts) { // Callbacks from cfile.c via WiresharkApplication::captureFileCallback -void MainWindow::captureFileReadStarted(const capture_file *cf) { +void MainWindow::captureFileOpened(const capture_file *cf) { + if (cf->window != this) return; cap_file_ = (capture_file *) cf; + + file_set_dialog_.fileOpened(cf); + setMenusForFileSet(true); +} + +void MainWindow::captureFileReadStarted(const capture_file *cf) { + if (cf != cap_file_) return; // tap_param_dlg_update(); /* Set up main window for a capture file. */ @@ -1278,6 +1299,9 @@ void MainWindow::captureFileClosed(const capture_file *cf) { if (cf != cap_file_) return; packets_bar_update(); + file_set_dialog_.fileClosed(); + setMenusForFileSet(false); + // Reset expert info indicator main_ui_->statusBar->hideExpert(); @@ -1473,11 +1497,6 @@ void MainWindow::recentActionTriggered() { } } -void MainWindow::openRecentCaptureFile(QString &cfPath) -{ - openCaptureFile(cfPath); -} - // File Menu @@ -1497,7 +1516,7 @@ void MainWindow::on_actionFileImport_triggered() } void MainWindow::on_actionFileClose_triggered() { - if (testCaptureFileClose(&cfile)) + if (testCaptureFileClose()) main_ui_->mainStack->setCurrentWidget(main_welcome_); } @@ -1511,6 +1530,31 @@ void MainWindow::on_actionFileSaveAs_triggered() saveAsCaptureFile(cap_file_, FALSE, TRUE); } +void MainWindow::on_actionFileSetListFiles_triggered() +{ + file_set_dialog_.exec(); +} + +void MainWindow::on_actionFileSetNextFile_triggered() +{ + fileset_entry *entry = fileset_get_next(); + + if (entry) { + QString new_cf_path = entry->fullname; + openCaptureFile(new_cf_path); + } +} + +void MainWindow::on_actionFileSetPreviousFile_triggered() +{ + fileset_entry *entry = fileset_get_previous(); + + if (entry) { + QString new_cf_path = entry->fullname; + openCaptureFile(new_cf_path); + } +} + // View Menu // Expand / collapse slots in proto_tree @@ -1667,7 +1711,7 @@ void MainWindow::on_actionStartCapture_triggered() } /* XXX - will closing this remove a temporary file? */ - if (testCaptureFileClose(&cfile, FALSE, *new QString(" before starting a new capture"))) + if (testCaptureFileClose(FALSE, *new QString(" before starting a new capture"))) startCapture(); } diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index c8e784edf8..aa368492ee 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -51,6 +51,7 @@ #include "packet_list.h" #include "display_filter_combo.h" #include "progress_bar.h" +#include "file_set_dialog.h" class QAction; @@ -81,6 +82,7 @@ private: capture_file *cap_file_; PacketList *packet_list_; QWidget *previous_focus_; + FileSetDialog file_set_dialog_; bool capture_stopping_; // Pipe input @@ -94,19 +96,19 @@ private: QSocketNotifier *pipe_notifier_; #endif - void openCaptureFile(QString& cf_path = *new QString()); void mergeCaptureFile(); void importCaptureFile(); void saveCaptureFile(capture_file *cf, bool stay_closed); void saveAsCaptureFile(capture_file *cf, bool must_support_comments, bool stay_closed); - bool testCaptureFileClose(capture_file *cf, bool from_quit = false, QString& before_what = *new QString()); - void captureStop(capture_file *cf); + bool testCaptureFileClose(bool from_quit = false, QString& before_what = *new QString()); + void captureStop(); void setMenusForCaptureFile(bool force_disable = false); void setMenusForCaptureInProgress(bool capture_in_progress = false); void setMenusForCaptureStopping(); // xxx set_menus_for_captured_packets // xxx set_menus_for_selected_packet + void setMenusForFileSet(bool enable_list_files); void updateForUnsavedChanges(); void setForCaptureInProgress(gboolean capture_in_progress = false); @@ -114,6 +116,8 @@ signals: void showProgress(progdlg_t **dlg_p, bool animate, const QString message, bool terminate_is_stop, bool *stop_flag, float pct); public slots: + void openCaptureFile(QString& cf_path = *new QString()); + #ifdef HAVE_LIBPCAP void captureCapturePrepared(capture_options *capture_opts); void captureCaptureUpdateStarted(capture_options *capture_opts); @@ -124,6 +128,7 @@ public slots: void captureCaptureFailed(capture_options *capture_opts); #endif + void captureFileOpened(const capture_file *cf); void captureFileReadStarted(const capture_file *cf); void captureFileReadFinished(const capture_file *cf); void captureFileClosing(const capture_file *cf); @@ -138,7 +143,6 @@ private slots: void updateRecentFiles(); void recentActionTriggered(); - void openRecentCaptureFile(QString& cfPath = *new QString()); void on_actionFileOpen_triggered(); void on_actionFileMerge_triggered(); @@ -146,6 +150,9 @@ private slots: void on_actionFileClose_triggered(); void on_actionFileSave_triggered(); void on_actionFileSaveAs_triggered(); + void on_actionFileSetListFiles_triggered(); + void on_actionFileSetNextFile_triggered(); + void on_actionFileSetPreviousFile_triggered(); void on_actionGoGoToPacket_triggered(); void resetPreviousFocus(); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index b25ca968af..bf30e0007e 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -90,7 +90,7 @@ 0 0 960 - 23 + 22 @@ -103,13 +103,13 @@ - + File Set - - - + + + @@ -120,7 +120,7 @@ - + @@ -618,17 +618,17 @@ Ctrl+P - + List Files - + Next File - + Previous File diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp index 583da79d6c..a1de3a71a7 100644 --- a/ui/qt/wireshark_application.cpp +++ b/ui/qt/wireshark_application.cpp @@ -211,6 +211,10 @@ void WiresharkApplication::captureFileCallback(int event, void * data) switch(event) { + case(cf_cb_file_opened): + g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened"); + emit captureFileOpened(cf); + break; case(cf_cb_file_closing): g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing"); emit captureFileClosing(cf); diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h index 879ce1e95f..c620ceff69 100644 --- a/ui/qt/wireshark_application.h +++ b/ui/qt/wireshark_application.h @@ -81,6 +81,7 @@ signals: void captureCaptureFailed(capture_options *capture_opts); #endif + void captureFileOpened(const capture_file *cf); void captureFileReadStarted(const capture_file *cf); void captureFileReadFinished(const capture_file *cf); void captureFileClosing(const capture_file *cf);