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.
28 #include "epan/expert.h"
29 #include "epan/filesystem.h"
31 #include "ui/main_statusbar.h"
32 #include "ui/profile.h"
33 #include "ui/utf8_entities.h"
35 #include "main_status_bar.h"
36 #include "profile_dialog.h"
39 #include <QHBoxLayout>
42 #include "tango_colors.h"
45 // XXX - The GTK+ code assigns priorities to these and pushes/pops accordingly.
55 Q_DECLARE_METATYPE(ProfileDialog::ProfileAction
)
57 // If we ever add support for multiple windows this will need to be replaced.
58 // See also: main_window.cpp
59 static MainStatusBar
*cur_main_status_bar_
= NULL
;
62 * Push a formatted temporary message onto the statusbar.
65 statusbar_push_temporary_msg(const gchar
*msg_format
, ...)
70 if (!cur_main_status_bar_
) return;
72 va_start(ap
, msg_format
);
73 push_msg
.vsprintf(msg_format
, ap
);
76 cur_main_status_bar_
->pushTemporaryStatus(push_msg
);
80 * Update the packets statusbar to the current values
83 packets_bar_update(void)
85 if (!cur_main_status_bar_
) return;
87 cur_main_status_bar_
->updateCaptureStatistics(NULL
);
90 MainStatusBar::MainStatusBar(QWidget
*parent
) :
96 QSplitter
*splitter
= new QSplitter(this);
98 QString
ready_msg(tr("Ready to load or capture"));
100 QString
ready_msg(tr("Ready to load file"));
102 QWidget
*info_progress
= new QWidget(this);
103 QHBoxLayout
*info_progress_hb
= new QHBoxLayout(info_progress
);
106 #if defined(Q_OS_WIN)
107 // Handles are the same color as widgets, at least on Windows 7.
108 splitter
->setHandleWidth(3);
109 splitter
->setStyleSheet(QString(
110 "QSplitter::handle {"
111 " border-left: 1px solid palette(mid);"
112 " border-right: 1px solid palette(mid);"
115 #elif defined(Q_OS_MAC)
116 expert_status_
.setAttribute(Qt::WA_MacSmallSize
, true);
119 expert_status_
.setTextFormat(Qt::RichText
);
120 expert_status_
.hide();
122 // XXX Add the comment icon
124 info_progress_hb
->setContentsMargins(0, 0, 0, 0);
126 info_status_
.setTemporaryContext(STATUS_CTX_TEMPORARY
);
128 info_progress_hb
->addWidget(&expert_status_
);
129 info_progress_hb
->addWidget(&info_status_
);
130 info_progress_hb
->addWidget(&progress_bar_
);
131 info_progress_hb
->addStretch(10);
133 splitter
->addWidget(info_progress
);
134 splitter
->addWidget(&packet_status_
);
135 splitter
->addWidget(&profile_status_
);
137 splitter
->setStretchFactor(0, 3);
138 splitter
->setStretchFactor(1, 3);
139 splitter
->setStretchFactor(2, 1);
141 addWidget(splitter
, 1);
143 cur_main_status_bar_
= this;
146 info_status_
.pushText(ready_msg
, STATUS_CTX_MAIN
);
147 packets_bar_update();
149 action
= ctx_menu_
.addAction(tr("Manage Profiles..."));
150 action
->setData(ProfileDialog::ShowProfiles
);
151 connect(action
, SIGNAL(triggered()), this, SLOT(manageProfile()));
152 ctx_menu_
.addSeparator();
153 action
= ctx_menu_
.addAction(tr("New..."));
154 action
->setData(ProfileDialog::NewProfile
);
155 connect(action
, SIGNAL(triggered()), this, SLOT(manageProfile()));
156 edit_action_
= ctx_menu_
.addAction(tr("Edit..."));
157 edit_action_
->setData(ProfileDialog::EditCurrentProfile
);
158 connect(edit_action_
, SIGNAL(triggered()), this, SLOT(manageProfile()));
159 delete_action_
= ctx_menu_
.addAction(tr("Delete"));
160 delete_action_
->setData(ProfileDialog::DeleteCurrentProfile
);
161 connect(delete_action_
, SIGNAL(triggered()), this, SLOT(manageProfile()));
162 ctx_menu_
.addSeparator();
163 profile_menu_
.setTitle(tr("Switch to"));
164 ctx_menu_
.addMenu(&profile_menu_
);
166 connect(wsApp
, SIGNAL(appInitialized()), splitter
, SLOT(show()));
167 connect(wsApp
, SIGNAL(appInitialized()), this, SLOT(pushProfileName()));
168 connect(&info_status_
, SIGNAL(toggleTemporaryFlash(bool)),
169 this, SLOT(toggleBackground(bool)));
170 connect(wsApp
, SIGNAL(captureCaptureUpdateContinue(capture_session
*)),
171 this, SLOT(updateCaptureStatistics(capture_session
*)));
172 connect(wsApp
, SIGNAL(configurationProfileChanged(const gchar
*)),
173 this, SLOT(pushProfileName()));
174 connect(&profile_status_
, SIGNAL(mousePressedAt(QPoint
,Qt::MouseButton
)),
175 this, SLOT(showProfileMenu(QPoint
,Qt::MouseButton
)));
178 void MainStatusBar::showExpert() {
182 void MainStatusBar::hideExpert() {
183 expert_status_
.hide();
186 void MainStatusBar::expertUpdate() {
187 QString img_text
= "<img src=\":/expert/expert_";
188 QString tt_text
= tr(" is the highest expert info level");
190 switch(expert_get_highest_severity()) {
192 img_text
.append("error");
193 tt_text
.prepend(tr("ERROR"));
196 img_text
.append("warn");
197 tt_text
.prepend(tr("WARNING"));
200 img_text
.append("note");
201 tt_text
.prepend(tr("NOTE"));
204 img_text
.append("chat");
205 tt_text
.prepend(tr("CHAT"));
208 // m_expertStatus.setText("<img src=\":/expert/expert_comment.png\"></img>");
211 img_text
.append("none");
212 tt_text
= tr("No expert info");
216 img_text
.append(".png\"></img>");
217 expert_status_
.setText(img_text
);
218 expert_status_
.setToolTip(tt_text
);
219 expert_status_
.show();
222 void MainStatusBar::setCaptureFile(capture_file
*cf
)
227 void MainStatusBar::pushTemporaryStatus(QString
&message
) {
228 info_status_
.pushText(message
, STATUS_CTX_TEMPORARY
);
231 void MainStatusBar::popTemporaryStatus() {
232 info_status_
.popText(STATUS_CTX_TEMPORARY
);
235 void MainStatusBar::pushFileStatus(QString
&message
) {
236 info_status_
.pushText(message
, STATUS_CTX_FILE
);
240 void MainStatusBar::popFileStatus() {
241 info_status_
.popText(STATUS_CTX_FILE
);
244 void MainStatusBar::pushFieldStatus(QString
&message
) {
245 if (message
.isNull()) {
248 info_status_
.pushText(message
, STATUS_CTX_FIELD
);
252 void MainStatusBar::popFieldStatus() {
253 info_status_
.popText(STATUS_CTX_FIELD
);
256 void MainStatusBar::pushFilterStatus(QString
&message
) {
257 info_status_
.pushText(message
, STATUS_CTX_FILTER
);
261 void MainStatusBar::popFilterStatus() {
262 info_status_
.popText(STATUS_CTX_FILTER
);
265 void MainStatusBar::pushPacketStatus(QString
&message
) {
266 packet_status_
.pushText(message
, STATUS_CTX_MAIN
);
269 void MainStatusBar::popPacketStatus() {
270 packet_status_
.popText(STATUS_CTX_MAIN
);
273 void MainStatusBar::pushProfileStatus(QString
&message
) {
274 profile_status_
.pushText(message
, STATUS_CTX_MAIN
);
277 void MainStatusBar::pushProfileName()
279 const gchar
*cur_profile
= get_profile_name();
280 QString status
= tr("Profile: ") + cur_profile
;
283 pushProfileStatus(status
);
285 if (profile_exists(cur_profile
, FALSE
) && strcmp (cur_profile
, DEFAULT_PROFILE
) != 0) {
286 edit_action_
->setEnabled(true);
287 delete_action_
->setEnabled(true);
289 edit_action_
->setEnabled(false);
290 delete_action_
->setEnabled(false);
294 void MainStatusBar::popProfileStatus() {
295 profile_status_
.popText(STATUS_CTX_MAIN
);
298 void MainStatusBar::updateCaptureStatistics(capture_session
*cap_session _U_
)
303 /* Do we have any packets? */
304 if ((!cap_session
|| cap_session
->cf
== cap_file_
) && cap_file_
&& cap_file_
->count
) {
305 packets_str
.append(QString(tr("Packets: %1 %4 Displayed: %2 %4 Marked: %3"))
306 .arg(cap_file_
->count
)
307 .arg(cap_file_
->displayed_count
)
308 .arg(cap_file_
->marked_count
)
309 .arg(UTF8_MIDDLE_DOT
));
310 if(cap_file_
->drops_known
) {
311 packets_str
.append(QString(tr(" %1 Dropped: %2")).arg(UTF8_MIDDLE_DOT
).arg(cap_file_
->drops
));
313 if(cap_file_
->ignored_count
> 0) {
314 packets_str
.append(QString(tr(" %1 Ignored: %2")).arg(UTF8_MIDDLE_DOT
).arg(cap_file_
->ignored_count
));
316 if(!cap_file_
->is_tempfile
) {
317 /* Loading an existing file */
318 gulong computed_elapsed
= cf_get_computed_elapsed(cap_file_
);
319 packets_str
.append(QString(tr(" %1 Load time: %2:%3.%4"))
320 .arg(UTF8_MIDDLE_DOT
)
321 .arg(computed_elapsed
/60000)
322 .arg(computed_elapsed
%60000/1000)
323 .arg(computed_elapsed
%1000));
327 packets_str
= tr("No Packets");
328 #endif // HAVE_LIBPCAP
331 #endif // HAVE_LIBPCAP
334 pushPacketStatus(packets_str
);
337 void MainStatusBar::showProfileMenu(const QPoint
&global_pos
, Qt::MouseButton button
)
340 profile_def
*profile
;
344 fl_entry
= edited_profile_list();
346 profile_menu_
.clear();
347 while (fl_entry
&& fl_entry
->data
) {
348 profile
= (profile_def
*) fl_entry
->data
;
349 pa
= profile_menu_
.addAction(profile
->name
);
350 connect(pa
, SIGNAL(triggered()), this, SLOT(switchToProfile()));
351 fl_entry
= g_list_next(fl_entry
);
354 if (button
== Qt::LeftButton
) {
355 profile_menu_
.exec(global_pos
);
357 ctx_menu_
.exec(global_pos
);
361 void MainStatusBar::toggleBackground(bool enabled
)
364 setStyleSheet(QString(
367 " background-color: #%2;"
370 .arg(ws_css_warn_text
, 6, 16, QChar('0'))
371 .arg(ws_css_warn_background
, 6, 16, QChar('0')));
377 void MainStatusBar::switchToProfile()
379 QAction
*pa
= qobject_cast
<QAction
*>(sender());
382 wsApp
->setConfigurationProfile(pa
->text().toUtf8().constData());
386 void MainStatusBar::manageProfile()
388 QAction
*pa
= qobject_cast
<QAction
*>(sender());
391 ProfileDialog cp_dialog
;
392 cp_dialog
.execAction(static_cast<ProfileDialog::ProfileAction
>(pa
->data().toInt()));
402 * indent-tabs-mode: nil
405 * ex: set shiftwidth=4 tabstop=8 expandtab:
406 * :indentSize=4:tabSize=8:noTabs=true: