3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
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.
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.
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.
24 #include "progress_frame.h"
25 #include <ui_progress_frame.h>
27 #include "ui/progress_dlg.h"
29 #include <QDialogButtonBox>
30 #include <QElapsedTimer>
31 #include <QGraphicsOpacityEffect>
33 #include <QPropertyAnimation>
35 #include "stock_icon_tool_button.h"
36 #include "wireshark_application.h"
39 // - Use a different icon?
40 // - Add an NSProgressIndicator to the dock icon on OS X.
41 // - Start adding the progress bar to dialogs.
42 // - Don't complain so loudly when the user stops a capture.
44 progdlg_t *create_progress_dlg(const gpointer top_level_window, const gchar *, const gchar *,
45 gboolean terminate_is_stop, gboolean *stop_flag) {
49 if (!top_level_window) {
53 main_window = qobject_cast<QWidget *>((QObject *)top_level_window);
59 pf = main_window->findChild<ProgressFrame *>();
64 return pf->showProgress(true, terminate_is_stop, stop_flag, 0);
68 delayed_create_progress_dlg(const gpointer top_level_window, const gchar *task_title, const gchar *item_title,
69 gboolean terminate_is_stop, gboolean *stop_flag,
70 const GTimeVal *, gfloat progress)
72 progdlg_t *progress_dialog = create_progress_dlg(top_level_window, task_title, item_title, terminate_is_stop, stop_flag);
73 update_progress_dlg(progress_dialog, progress, item_title);
74 return progress_dialog;
78 * Update the progress information of the progress bar box.
80 static const int app_update_freq_ = 100; // ms
82 update_progress_dlg(progdlg_t *dlg, gfloat percentage, const gchar *)
84 if (!dlg || dlg->elapsed_timer->elapsed() < app_update_freq_) return;
86 dlg->progress_frame->setValue(percentage * 100);
89 * Flush out the update and process any input events.
91 WiresharkApplication::processEvents();
92 dlg->elapsed_timer->restart();
96 * Destroy the progress bar.
99 destroy_progress_dlg(progdlg_t *dlg)
101 dlg->progress_frame->hide();
104 ProgressFrame::ProgressFrame(QWidget *parent) :
106 ui(new Ui::ProgressFrame)
107 , terminate_is_stop_(false)
109 #if !defined(Q_OS_MAC) || QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
114 #ifdef QWINTASKBARPROGRESS_H
115 , update_taskbar_(false)
116 , taskbar_progress_(NULL)
121 progress_dialog_.progress_frame = this;
122 progress_dialog_.elapsed_timer = new QElapsedTimer();
123 progress_dialog_.top_level_window = window();
125 ui->progressBar->setStyleSheet(QString(
128 " min-height: 0.5em;"
130 " border-bottom: 0px;"
132 " background: transparent;"
135 ui->stopButton->setStockIcon("x-filter-clear");
136 ui->stopButton->setIconSize(QSize(14, 14));
137 ui->stopButton->setStyleSheet(
140 " background: transparent;" // Disables platform style on Windows.
143 " min-height: 0.8em;"
150 #if !defined(Q_OS_MAC) || QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
151 effect_ = new QGraphicsOpacityEffect(this);
152 animation_ = new QPropertyAnimation(effect_, "opacity", this);
155 connect(this, SIGNAL(showRequested(bool,bool,gboolean*)),
156 this, SLOT(show(bool,bool,gboolean*)));
160 ProgressFrame::~ProgressFrame()
163 delete progress_dialog_.elapsed_timer;
166 struct progdlg *ProgressFrame::showProgress(bool animate, bool terminate_is_stop, gboolean *stop_flag, int value)
168 setMaximumValue(100);
169 ui->progressBar->setValue(value);
170 progress_dialog_.elapsed_timer->start();
171 emit showRequested(animate, terminate_is_stop, stop_flag);
172 return &progress_dialog_;
175 progdlg *ProgressFrame::showBusy(bool animate, bool terminate_is_stop, gboolean *stop_flag)
178 emit showRequested(animate, terminate_is_stop, stop_flag);
179 return &progress_dialog_;
182 void ProgressFrame::addToButtonBox(QDialogButtonBox *button_box, QObject *main_window)
184 // We have a ProgressFrame in the main status bar which is controlled
185 // from the capture file and other parts of the application via
186 // create_progress_dlg and delayed_create_progress_dlg.
187 // Create a new ProgressFrame and pair it with the main instance.
188 ProgressFrame *main_progress_frame = main_window->findChild<ProgressFrame *>();
189 if (!button_box || !main_progress_frame) return;
191 QBoxLayout *layout = qobject_cast<QBoxLayout *>(button_box->layout());
194 ProgressFrame *progress_frame = new ProgressFrame(button_box);
196 // Insert ourselves after the first spacer we find, otherwise the
197 // far right of the button box.
198 int idx = layout->count();
199 for (int i = 0; i < layout->count(); i++) {
200 if (layout->itemAt(i)->spacerItem()) {
205 layout->insertWidget(idx, progress_frame);
207 int one_em = progress_frame->fontMetrics().height();
208 progress_frame->setMaximumWidth(one_em * 8);
209 connect(main_progress_frame, SIGNAL(showRequested(bool,bool,gboolean*)),
210 progress_frame, SLOT(show(bool,bool,gboolean*)));
211 connect(main_progress_frame, SIGNAL(maximumValueChanged(int)),
212 progress_frame, SLOT(setMaximumValue(int)));
213 connect(main_progress_frame, SIGNAL(valueChanged(int)),
214 progress_frame, SLOT(setValue(int)));
215 connect(main_progress_frame, SIGNAL(setHidden()),
216 progress_frame, SLOT(hide()));
218 connect(progress_frame, SIGNAL(stopLoading()),
219 main_progress_frame, SIGNAL(stopLoading()));
222 void ProgressFrame::captureFileClosing()
224 // Hide any paired ProgressFrames and disconnect from them.
226 disconnect(SIGNAL(showRequested(bool,bool,gboolean*)));
227 disconnect(SIGNAL(maximumValueChanged(int)));
228 disconnect(SIGNAL(valueChanged(int)));
230 connect(this, SIGNAL(showRequested(bool,bool,gboolean*)),
231 this, SLOT(show(bool,bool,gboolean*)));
234 void ProgressFrame::setValue(int value)
236 ui->progressBar->setValue(value);
237 emit valueChanged(value);
240 #if !defined(Q_OS_MAC) || QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
241 void ProgressFrame::timerEvent(QTimerEvent *event)
243 if (event->timerId() == show_timer_) {
244 killTimer(show_timer_);
247 this->setGraphicsEffect(effect_);
249 animation_->setDuration(750);
250 animation_->setStartValue(0.1);
251 animation_->setEndValue(1.0);
252 animation_->setEasingCurve(QEasingCurve::InOutQuad);
260 void ProgressFrame::hide()
262 progress_dialog_.elapsed_timer->invalidate();
263 #if !defined(Q_OS_MAC) || QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
268 #ifdef QWINTASKBARPROGRESS_H
269 if (taskbar_progress_) {
270 taskbar_progress_->reset();
271 taskbar_progress_->hide();
276 void ProgressFrame::on_stopButton_clicked()
281 const int show_delay_ = 500; // ms
282 void ProgressFrame::show(bool animate, bool terminate_is_stop, gboolean *stop_flag)
284 terminate_is_stop_ = terminate_is_stop;
285 stop_flag_ = stop_flag;
288 ui->stopButton->show();
290 ui->stopButton->hide();
293 #if !defined(Q_OS_MAC) || QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
295 show_timer_ = startTimer(show_delay_);
304 #ifdef QWINTASKBARPROGRESS_H
305 // windowHandle() is picky about returning a non-NULL value so we check it
307 if (update_taskbar_ && !taskbar_progress_ && window()->windowHandle()) {
308 QWinTaskbarButton *taskbar_button = new QWinTaskbarButton(this);
309 if (taskbar_button) {
310 taskbar_button->setWindow(window()->windowHandle());
311 taskbar_progress_ = taskbar_button->progress();
312 connect(this, SIGNAL(valueChanged(int)), taskbar_progress_, SLOT(setValue(int)));
315 if (taskbar_progress_) {
316 taskbar_progress_->show();
317 taskbar_progress_->resume();
322 void ProgressFrame::setMaximumValue(int value)
324 ui->progressBar->setMaximum(value);
325 emit maximumValueChanged(value);
334 * indent-tabs-mode: nil
337 * ex: set shiftwidth=4 tabstop=8 expandtab:
338 * :indentSize=4:tabSize=8:noTabs=true: