MSWSP: add parse_CNatLanguageRestriction()
[wireshark-wip.git] / ui / qt / search_frame.cpp
blob8b24135afbef907b01230aa5e81deb2c57fe972d
1 /* search_frame.cpp
3 * $Id$
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "search_frame.h"
25 #include "ui_search_frame.h"
27 #include <epan/proto.h>
28 #include <epan/strutil.h>
30 #include "wireshark_application.h"
31 #include <QKeyEvent>
32 #include <QCheckBox>
34 const int in_packet_list = 0;
35 const int in_proto_tree = 1;
36 const int in_bytes = 2;
38 const int df_search = 0;
39 const int hex_search = 1;
40 const int string_search = 2;
42 const int narrow_and_wide_chars = 0;
43 const int narrow_chars = 1;
44 const int wide_chars = 2;
46 SearchFrame::SearchFrame(QWidget *parent) :
47 AccordionFrame(parent),
48 sf_ui_(new Ui::SearchFrame),
49 cap_file_(NULL)
51 sf_ui_->setupUi(this);
53 #ifdef Q_OS_MAC
54 foreach (QWidget *w, findChildren<QWidget *>()) {
55 w->setAttribute(Qt::WA_MacSmallSize, true);
57 #endif
58 sf_ui_->searchTypeComboBox->setCurrentIndex(0);
59 enableWidgets();
62 SearchFrame::~SearchFrame()
64 delete sf_ui_;
67 void SearchFrame::animatedShow()
69 sf_ui_->searchLineEdit->setFocus();
71 AccordionFrame::animatedShow();
74 void SearchFrame::findNext()
76 if (!cap_file_) return;
78 cap_file_->dir = SD_FORWARD;
79 if (isHidden()) {
80 animatedShow();
81 return;
83 on_findButton_clicked();
86 void SearchFrame::findPrevious()
88 if (!cap_file_) return;
90 cap_file_->dir = SD_BACKWARD;
91 if (isHidden()) {
92 animatedShow();
93 return;
95 on_findButton_clicked();
98 void SearchFrame::setCaptureFile(capture_file *cf)
100 cap_file_ = cf;
101 if (!cf && isVisible()) {
102 animatedHide();
104 enableWidgets();
107 void SearchFrame::findFrameWithFilter(QString &filter)
109 animatedShow();
110 sf_ui_->searchLineEdit->setText(filter);
111 sf_ui_->searchTypeComboBox->setCurrentIndex(0);
112 enableWidgets();
115 void SearchFrame::keyPressEvent(QKeyEvent *event)
117 if (wsApp->focusWidget() == sf_ui_->searchLineEdit) {
118 if (event->modifiers() == Qt::NoModifier) {
119 if (event->key() == Qt::Key_Escape) {
120 on_cancelButton_clicked();
121 } else if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
122 on_findButton_clicked();
125 return; // searchLineEdit didn't want it and we don't either.
129 void SearchFrame::enableWidgets()
131 if (cap_file_) {
132 setEnabled(true);
133 } else {
134 setEnabled(false);
135 return;
138 dfilter_t *dfp = NULL;
139 bool enable = sf_ui_->searchTypeComboBox->currentIndex() == string_search;
140 sf_ui_->searchInComboBox->setEnabled(enable);
141 sf_ui_->caseCheckBox->setEnabled(enable);
142 sf_ui_->charEncodingComboBox->setEnabled(enable);
144 switch (sf_ui_->searchTypeComboBox->currentIndex()) {
145 case df_search:
146 // XXX - Merge this with DisplayFitlerEdit::checkFilter
147 if (dfilter_compile(sf_ui_->searchLineEdit->text().toUtf8().constData(), &dfp)) {
148 GPtrArray *depr = NULL;
149 if (dfp != NULL) {
150 depr = dfilter_deprecated_tokens(dfp);
152 if (sf_ui_->searchLineEdit->text().isEmpty()) {
153 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Empty);
154 } else if (depr) {
155 /* You keep using that word. I do not think it means what you think it means. */
156 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Deprecated);
157 } else {
158 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Valid);
160 dfilter_free(dfp);
161 } else {
162 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
164 break;
165 case hex_search:
166 if (sf_ui_->searchLineEdit->text().isEmpty()) {
167 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
168 } else {
169 guint8 *bytes;
170 size_t nbytes;
171 bytes = convert_string_to_hex(sf_ui_->searchLineEdit->text().toUtf8().constData(), &nbytes);
172 if (bytes == NULL)
173 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
174 else {
175 g_free(bytes);
176 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Valid);
179 break;
180 case string_search:
181 if (sf_ui_->searchLineEdit->text().isEmpty()) {
182 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
183 } else {
184 sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Valid);
186 break;
187 default:
188 QString err_string = tr("No valid search type selected. Please report this to the development team.");
189 emit pushFilterSyntaxStatus(err_string);
190 return;
193 if (sf_ui_->searchLineEdit->text().isEmpty() || sf_ui_->searchLineEdit->syntaxState() == SyntaxLineEdit::Invalid) {
194 sf_ui_->findButton->setEnabled(false);
195 } else {
196 sf_ui_->findButton->setEnabled(true);
200 void SearchFrame::on_searchTypeComboBox_currentIndexChanged(int index)
202 Q_UNUSED(index);
203 enableWidgets();
206 void SearchFrame::on_searchLineEdit_textChanged(const QString &search_string)
208 Q_UNUSED(search_string);
209 enableWidgets();
212 void SearchFrame::on_findButton_clicked()
214 guint8 *bytes = NULL;
215 size_t nbytes;
216 char *string = NULL;
217 dfilter_t *dfp;
218 gboolean found_packet = FALSE;
219 QString err_string;
221 if (!cap_file_) {
222 return;
225 cap_file_->hex = FALSE;
226 cap_file_->string = FALSE;
227 cap_file_->case_type = FALSE;
228 cap_file_->packet_data = FALSE;
229 cap_file_->decode_data = FALSE;
230 cap_file_->summary_data = FALSE;
231 cap_file_->scs_type = SCS_NARROW_AND_WIDE;
233 switch (sf_ui_->searchTypeComboBox->currentIndex()) {
234 case df_search:
235 if (!dfilter_compile(sf_ui_->searchLineEdit->text().toUtf8().constData(), &dfp)) {
236 err_string = tr("Invalid filter.");
237 emit pushFilterSyntaxStatus(err_string);
238 return;
241 if (dfp == NULL) {
242 err_string = tr("That filter doesn't test anything.");
243 emit pushFilterSyntaxStatus(err_string);
244 return;
246 break;
247 case hex_search:
248 bytes = convert_string_to_hex(sf_ui_->searchLineEdit->text().toUtf8().constData(), &nbytes);
249 if (bytes == NULL) {
250 err_string = tr("That's not a valid hex string.");
251 emit pushFilterSyntaxStatus(err_string);
252 return;
254 cap_file_->hex = TRUE;
255 break;
256 case string_search:
257 if (sf_ui_->searchLineEdit->text().isEmpty()) {
258 err_string = tr("You didn't specify any text for which to search.");
259 emit pushFilterSyntaxStatus(err_string);
260 return;
262 cap_file_->string = TRUE;
263 cap_file_->case_type = sf_ui_->caseCheckBox->isChecked() ? FALSE : TRUE;
264 switch (sf_ui_->charEncodingComboBox->currentIndex()) {
265 case narrow_and_wide_chars:
266 cap_file_->scs_type = SCS_NARROW_AND_WIDE;
267 break;
268 case narrow_chars:
269 cap_file_->scs_type = SCS_NARROW;
270 break;
271 case wide_chars:
272 cap_file_->scs_type = SCS_WIDE;
273 break;
274 default:
275 err_string = tr("No valid character set selected. Please report this to the development team.");
276 emit pushFilterSyntaxStatus(err_string);
277 return;
279 string = convert_string_case(sf_ui_->searchLineEdit->text().toUtf8().constData(), cap_file_->case_type);
280 break;
281 default:
282 err_string = tr("No valid search type selected. Please report this to the development team.");
283 emit pushFilterSyntaxStatus(err_string);
284 return;
287 switch (sf_ui_->searchInComboBox->currentIndex()) {
288 case in_packet_list:
289 cap_file_->summary_data = TRUE;
290 break;
291 case in_proto_tree:
292 cap_file_->decode_data = TRUE;
293 break;
294 case in_bytes:
295 cap_file_->packet_data = TRUE;
296 break;
297 default:
298 err_string = tr("No valid search area selected. Please report this to the development team.");
299 emit pushFilterSyntaxStatus(err_string);
300 return;
303 g_free(cap_file_->sfilter);
304 cap_file_->sfilter = g_strdup(sf_ui_->searchLineEdit->text().toUtf8().constData());
306 if (cap_file_->hex) {
307 /* Hex value in packet data */
308 found_packet = cf_find_packet_data(cap_file_, bytes, nbytes, cap_file_->dir);
309 g_free(bytes);
310 if (!found_packet) {
311 /* We didn't find a packet */
312 err_string = tr("No packet contained those bytes.");
313 emit pushFilterSyntaxStatus(err_string);
314 return;
316 } else if (cap_file_->string) {
317 if (cap_file_->summary_data) {
318 /* String in the Info column of the summary line */
319 found_packet = cf_find_packet_summary_line(cap_file_, string, cap_file_->dir);
320 g_free(string);
321 if (!found_packet) {
322 err_string = tr("No packet contained that string in its Info column.");
323 emit pushFilterSyntaxStatus(err_string);
324 return;
326 } else if (cap_file_->decode_data) {
327 /* String in the protocol tree headings */
328 found_packet = cf_find_packet_protocol_tree(cap_file_, string, cap_file_->dir);
329 g_free(string);
330 if (!found_packet) {
331 err_string = tr("No packet contained that string in its dissected display.");
332 emit pushFilterSyntaxStatus(err_string);
333 return;
335 } else if (cap_file_->packet_data && string) {
336 /* String in the ASCII-converted packet data */
337 found_packet = cf_find_packet_data(cap_file_, (guint8 *) string, strlen(string), cap_file_->dir);
338 g_free(string);
339 if (!found_packet) {
340 err_string = tr("No packet contained that string in its converted data.");
341 emit pushFilterSyntaxStatus(err_string);
342 return;
345 } else {
346 /* Search via display filter */
347 found_packet = cf_find_packet_dfilter(cap_file_, dfp, cap_file_->dir);
348 dfilter_free(dfp);
349 if (!found_packet) {
350 err_string = tr("No packet matched that filter.");
351 emit pushFilterSyntaxStatus(err_string);
352 g_free(bytes);
353 return;
358 void SearchFrame::on_cancelButton_clicked()
360 animatedHide();
364 * Editor modelines
366 * Local Variables:
367 * c-basic-offset: 4
368 * tab-width: 8
369 * indent-tabs-mode: nil
370 * End:
372 * ex: set shiftwidth=4 tabstop=8 expandtab:
373 * :indentSize=4:tabSize=8:noTabs=true: