summaryrefslogtreecommitdiff
path: root/ui/qt/search_frame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/search_frame.cpp')
-rw-r--r--ui/qt/search_frame.cpp373
1 files changed, 373 insertions, 0 deletions
diff --git a/ui/qt/search_frame.cpp b/ui/qt/search_frame.cpp
new file mode 100644
index 0000000000..a2b9e138ea
--- /dev/null
+++ b/ui/qt/search_frame.cpp
@@ -0,0 +1,373 @@
+/* search_frame.cpp
+ *
+ * $Id: splash_overlay.cpp 45941 2012-11-05 22:43:15Z 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "search_frame.h"
+#include "ui_search_frame.h"
+
+#include <epan/proto.h>
+#include <epan/strutil.h>
+
+#include "wireshark_application.h"
+#include <QKeyEvent>
+#include <QCheckBox>
+
+const int in_packet_list = 0;
+const int in_proto_tree = 1;
+const int in_bytes = 2;
+
+const int df_search = 0;
+const int hex_search = 1;
+const int string_search = 2;
+
+const int narrow_and_wide_chars = 0;
+const int narrow_chars = 1;
+const int wide_chars = 2;
+
+SearchFrame::SearchFrame(QWidget *parent) :
+ QFrame(parent),
+ sf_ui_(new Ui::SearchFrame),
+ cap_file_(NULL)
+{
+ sf_ui_->setupUi(this);
+
+#ifdef Q_WS_MAC
+ foreach (QWidget *w, findChildren<QWidget *>()) {
+ w->setAttribute(Qt::WA_MacSmallSize, true);
+ }
+#endif
+ sf_ui_->searchTypeComboBox->setCurrentIndex(0);
+ enableWidgets();
+}
+
+SearchFrame::~SearchFrame()
+{
+ delete sf_ui_;
+}
+
+void SearchFrame::show()
+{
+ sf_ui_->searchLineEdit->setFocus();
+ QFrame::show();
+}
+
+void SearchFrame::findNext()
+{
+ if (!cap_file_) return;
+
+ cap_file_->dir = SD_FORWARD;
+ if (isHidden()) {
+ show();
+ return;
+ }
+ on_findButton_clicked();
+}
+
+void SearchFrame::findPrevious()
+{
+ if (!cap_file_) return;
+
+ cap_file_->dir = SD_BACKWARD;
+ if (isHidden()) {
+ show();
+ return;
+ }
+ on_findButton_clicked();
+}
+
+void SearchFrame::setCaptureFile(capture_file *cf)
+{
+ cap_file_ = cf;
+ if (!cf && isVisible()) {
+ hide();
+ }
+ enableWidgets();
+}
+
+void SearchFrame::findFrameWithFilter(QString &filter)
+{
+ show();
+ sf_ui_->searchLineEdit->setText(filter);
+ sf_ui_->searchTypeComboBox->setCurrentIndex(0);
+ enableWidgets();
+}
+
+void SearchFrame::keyPressEvent(QKeyEvent *event)
+{
+ if (wsApp->focusWidget() == sf_ui_->searchLineEdit) {
+ if (event->modifiers() == Qt::NoModifier) {
+ if (event->key() == Qt::Key_Escape) {
+ on_cancelButton_clicked();
+ } else if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ on_findButton_clicked();
+ }
+ }
+ return; // searchLineEdit didn't want it and we don't either.
+ }
+}
+
+void SearchFrame::enableWidgets()
+{
+ if (cap_file_) {
+ setEnabled(true);
+ } else {
+ setEnabled(false);
+ return;
+ }
+
+ dfilter_t *dfp = NULL;
+ bool enable = sf_ui_->searchTypeComboBox->currentIndex() == string_search;
+ sf_ui_->searchInComboBox->setEnabled(enable);
+ sf_ui_->caseCheckBox->setEnabled(enable);
+ sf_ui_->charEncodingComboBox->setEnabled(enable);
+
+ switch (sf_ui_->searchTypeComboBox->currentIndex()) {
+ case df_search:
+ // XXX - Merge this with DisplayFitlerEdit::checkFilter
+ if (dfilter_compile(sf_ui_->searchLineEdit->text().toUtf8().constData(), &dfp)) {
+ GPtrArray *depr = NULL;
+ if (dfp != NULL) {
+ depr = dfilter_deprecated_tokens(dfp);
+ }
+ if (sf_ui_->searchLineEdit->text().isEmpty()) {
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Empty);
+ } else if (depr) {
+ /* You keep using that word. I do not think it means what you think it means. */
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Deprecated);
+ } else {
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Valid);
+ }
+ dfilter_free(dfp);
+ } else {
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
+ }
+ break;
+ case hex_search:
+ if (sf_ui_->searchLineEdit->text().isEmpty()) {
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
+ } else {
+ guint8 *bytes = NULL;
+ size_t nbytes;
+ bytes = convert_string_to_hex(sf_ui_->searchLineEdit->text().toUtf8().constData(), &nbytes);
+ if (bytes == NULL)
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
+ else {
+ g_free(bytes);
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Valid);
+ }
+ }
+ break;
+ case string_search:
+ if (sf_ui_->searchLineEdit->text().isEmpty()) {
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
+ } else {
+ sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Valid);
+ }
+ break;
+ default:
+ QString err_string = tr("No valid search type selected. Please report this to the development team.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+
+ if (sf_ui_->searchLineEdit->text().isEmpty() || sf_ui_->searchLineEdit->syntaxState() == SyntaxLineEdit::Invalid) {
+ sf_ui_->findButton->setEnabled(false);
+ } else {
+ sf_ui_->findButton->setEnabled(true);
+ }
+}
+
+void SearchFrame::on_searchTypeComboBox_currentIndexChanged(int index)
+{
+ Q_UNUSED(index);
+ enableWidgets();
+}
+
+void SearchFrame::on_searchLineEdit_textChanged(const QString &search_string)
+{
+ Q_UNUSED(search_string);
+ enableWidgets();
+}
+
+void SearchFrame::on_findButton_clicked()
+{
+ guint8 *bytes = NULL;
+ size_t nbytes;
+ char *string = NULL;
+ dfilter_t *dfp;
+ gboolean found_packet = FALSE;
+ QString err_string;
+
+ if (!cap_file_) {
+ return;
+ }
+
+ cap_file_->hex = FALSE;
+ cap_file_->string = FALSE;
+ cap_file_->case_type = FALSE;
+ cap_file_->packet_data = FALSE;
+ cap_file_->decode_data = FALSE;
+ cap_file_->summary_data = FALSE;
+ cap_file_->scs_type = SCS_NARROW_AND_WIDE;
+
+ switch (sf_ui_->searchTypeComboBox->currentIndex()) {
+ case df_search:
+ if (!dfilter_compile(sf_ui_->searchLineEdit->text().toUtf8().constData(), &dfp)) {
+ err_string = tr("Invalid filter.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+
+ if (dfp == NULL) {
+ err_string = tr("That filter doesn't test anything.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ break;
+ case hex_search:
+ bytes = convert_string_to_hex(sf_ui_->searchLineEdit->text().toUtf8().constData(), &nbytes);
+ if (bytes == NULL) {
+ err_string = tr("That's not a valid hex string.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ cap_file_->hex = TRUE;
+ break;
+ case string_search:
+ if (sf_ui_->searchLineEdit->text().isEmpty()) {
+ err_string = tr("You didn't specify any text for which to search.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ cap_file_->string = TRUE;
+ cap_file_->case_type = sf_ui_->caseCheckBox->isChecked() ? FALSE : TRUE;
+ switch (sf_ui_->charEncodingComboBox->currentIndex()) {
+ case narrow_and_wide_chars:
+ cap_file_->scs_type = SCS_NARROW_AND_WIDE;
+ break;
+ case narrow_chars:
+ cap_file_->scs_type = SCS_NARROW;
+ break;
+ case wide_chars:
+ cap_file_->scs_type = SCS_WIDE;
+ break;
+ default:
+ err_string = tr("No valid character set selected. Please report this to the development team.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ string = convert_string_case(sf_ui_->searchLineEdit->text().toUtf8().constData(), cap_file_->case_type);
+ break;
+ default:
+ err_string = tr("No valid search type selected. Please report this to the development team.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+
+ switch (sf_ui_->searchInComboBox->currentIndex()) {
+ case in_packet_list:
+ cap_file_->summary_data = TRUE;
+ break;
+ case in_proto_tree:
+ cap_file_->decode_data = TRUE;
+ break;
+ case in_bytes:
+ cap_file_->packet_data = TRUE;
+ break;
+ default:
+ err_string = tr("No valid search area selected. Please report this to the development team.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+
+ g_free(cap_file_->sfilter);
+ cap_file_->sfilter = g_strdup(sf_ui_->searchLineEdit->text().toUtf8().constData());
+
+ if (cap_file_->hex) {
+ /* Hex value in packet data */
+ found_packet = cf_find_packet_data(cap_file_, bytes, nbytes, cap_file_->dir);
+ g_free(bytes);
+ if (!found_packet) {
+ /* We didn't find a packet */
+ err_string = tr("No packet contained those bytes.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ } else if (cap_file_->string) {
+ if (cap_file_->summary_data) {
+ /* String in the Info column of the summary line */
+ found_packet = cf_find_packet_summary_line(cap_file_, string, cap_file_->dir);
+ g_free(string);
+ if (!found_packet) {
+ err_string = tr("No packet contained that string in its Info column.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ } else if (cap_file_->decode_data) {
+ /* String in the protocol tree headings */
+ found_packet = cf_find_packet_protocol_tree(cap_file_, string, cap_file_->dir);
+ g_free(string);
+ if (!found_packet) {
+ err_string = tr("No packet contained that string in its dissected display.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ } else if (cap_file_->packet_data && string) {
+ /* String in the ASCII-converted packet data */
+ found_packet = cf_find_packet_data(cap_file_, (guint8 *) string, strlen(string), cap_file_->dir);
+ g_free(string);
+ if (!found_packet) {
+ err_string = tr("No packet contained that string in its converted data.");
+ emit pushFilterSyntaxStatus(err_string);
+ return;
+ }
+ }
+ } else {
+ /* Search via display filter */
+ found_packet = cf_find_packet_dfilter(cap_file_, dfp, cap_file_->dir);
+ dfilter_free(dfp);
+ if (!found_packet) {
+ err_string = tr("No packet matched that filter.");
+ emit pushFilterSyntaxStatus(err_string);
+ g_free(bytes);
+ return;
+ }
+ }
+}
+
+void SearchFrame::on_cancelButton_clicked()
+{
+ hide();
+}
+
+/*
+ * 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:
+ */