Qt: Protect against unintentional "no capture file" window status
[metze/wireshark/wip.git] / ui / qt / wireshark_dialog.cpp
1 /* wireshark_dialog.cpp
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include "config.h"
23
24 #include <glib.h>
25
26 #include "cfile.h"
27
28 #include <epan/packet.h>
29 #include <epan/tap.h>
30
31 #include "wireshark_dialog.h"
32
33 #include <QMessageBox>
34
35 #include "wireshark_application.h"
36
37 // To do:
38 // - Use a dynamic property + Q_PROPERTY for the subtitle.
39 // - Save and load recent geometry.
40 // - Make our nested event loop more robust. See tryDeleteLater for details.
41
42 WiresharkDialog::WiresharkDialog(QWidget &, CaptureFile &capture_file) :
43     QDialog(NULL, Qt::Window),
44     cap_file_(capture_file),
45     file_closed_(false),
46     retap_depth_(0),
47     dialog_closed_(false)
48 {
49     setWindowIcon(wsApp->normalIcon());
50     setWindowTitleFromSubtitle();
51
52     connect(&cap_file_, SIGNAL(captureFileRetapStarted()), this, SLOT(beginRetapPackets()));
53     connect(&cap_file_, SIGNAL(captureFileRetapFinished()), this, SLOT(endRetapPackets()));
54     connect(&cap_file_, SIGNAL(captureFileClosing()), this, SLOT(captureFileClosing()));
55     connect(&cap_file_, SIGNAL(captureFileClosed()), this, SLOT(captureFileClosed()));
56 }
57
58 void WiresharkDialog::accept()
59 {
60     QDialog::accept();
61
62     // Cancel any taps in progress?
63     // cap_file_.setCaptureStopFlag();
64     removeTapListeners();
65     dialog_closed_ = true;
66     tryDeleteLater();
67 }
68
69 // XXX Should we do this in WiresharkDialog?
70 void WiresharkDialog::reject()
71 {
72     QDialog::reject();
73
74     // Cancel any taps in progress?
75     // cap_file_.setCaptureStopFlag();
76     removeTapListeners();
77     dialog_closed_ = true;
78     tryDeleteLater();
79 }
80
81
82 void WiresharkDialog::setWindowSubtitle(const QString &subtitle)
83 {
84     subtitle_ = subtitle;
85     setWindowTitleFromSubtitle();
86 }
87
88 void WiresharkDialog::setWindowTitleFromSubtitle()
89 {
90     QString title = wsApp->windowTitleString(QStringList() << subtitle_ << cap_file_.fileTitle());
91     QDialog::setWindowTitle(title);
92 }
93
94 // See if we can destroy ourselves. The user may have clicked "Close" while
95 // we were deep in the bowels of a routine that retaps packets. Track our
96 // tapping state using retap_depth_ and our closed state using dialog_closed_.
97 //
98 // The Delta Object Rules (http://delta.affinix.com/dor/) page on nested
99 // event loops effectively says "don't do that." However, we don't really
100 // have a choice if we want to have a usable application that retaps packets.
101
102 void WiresharkDialog::tryDeleteLater()
103 {
104     if (retap_depth_ < 1 && dialog_closed_) {
105         disconnect();
106         deleteLater();
107     }
108 }
109
110 void WiresharkDialog::updateWidgets()
111 {
112     setWindowTitleFromSubtitle();
113 }
114
115 bool WiresharkDialog::registerTapListener(const char *tap_name, void *tap_data, const char *filter, guint flags, void(*tap_reset)(void *), gboolean(*tap_packet)(void *, struct _packet_info *, struct epan_dissect *, const void *), void(*tap_draw)(void *))
116 {
117     GString *error_string = register_tap_listener(tap_name, tap_data, filter, flags,
118                                                   tap_reset, tap_packet, tap_draw);
119     if (error_string) {
120         QMessageBox::warning(this, tr("Failed to attach to tap \"%1\"").arg(tap_name),
121                              error_string->str);
122         g_string_free(error_string, TRUE);
123         return false;
124     }
125
126     tap_listeners_ << tap_data;
127     return true;
128 }
129
130 void WiresharkDialog::endRetapPackets()
131 {
132     retap_depth_--;
133     tryDeleteLater();
134 }
135
136 void WiresharkDialog::removeTapListeners()
137 {
138     while (!tap_listeners_.isEmpty()) {
139         remove_tap_listener(tap_listeners_.takeFirst());
140     }
141 }
142
143 void WiresharkDialog::captureFileClosing()
144 {
145     if (file_closed_)
146         return;
147
148     removeTapListeners();
149     updateWidgets();
150 }
151
152 void WiresharkDialog::captureFileClosed()
153 {
154     if (file_closed_)
155         return;
156
157     removeTapListeners();
158     updateWidgets();
159     file_closed_ = true;
160 }
161
162 /*
163  * Editor modelines
164  *
165  * Local Variables:
166  * c-basic-offset: 4
167  * tab-width: 8
168  * indent-tabs-mode: nil
169  * End:
170  *
171  * ex: set shiftwidth=4 tabstop=8 expandtab:
172  * :indentSize=4:tabSize=8:noTabs=true:
173  */