1 /* splash_overlay.cpp
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9 
10 #include "splash_overlay.h"
11 #include <ui_splash_overlay.h>
12 #include "wireshark_application.h"
13 
14 #include <QPainter>
15 
16 #include "ui/util.h"
17 #include <wsutil/utf8_entities.h>
18 #include <ui/qt/utils/tango_colors.h>
19 
20 #ifdef HAVE_LUA
21 #include "epan/wslua/init_wslua.h"
22 #endif
23 
24 #include "extcap.h"
25 
26 // Uncomment to slow the update progress
27 //#define THROTTLE_STARTUP 1
28 
29 /*
30  * Update frequency for the splash screen, given in milliseconds.
31  */
32 const int info_update_freq_ = 65; // ~15 fps
33 
34 void splash_update(register_action_e action, const char *message, void *) {
35     emit wsApp->registerUpdate(action, message);
36 }
37 
38 SplashOverlay::SplashOverlay(QWidget *parent) :
39     QWidget(parent),
40     so_ui_(new Ui::SplashOverlay),
41     last_action_(RA_NONE),
42     register_cur_(0)
43 {
44     so_ui_->setupUi(this);
45 
46     int register_max = RA_BASE_COUNT;
47 #ifdef HAVE_LUA
48     register_max++;
49 #endif
50     register_max++;
51 
52     so_ui_->progressBar->setMaximum(register_max);
53     elapsed_timer_.start();
54 
55     QColor bg = QColor(tango_aluminium_6);
56     bg.setAlphaF(0.2);
57     QPalette pal;
58     pal.setColor(QPalette::Window, bg);
59     setPalette(pal);
60     setAutoFillBackground(true);
61 
62     setStyleSheet(QString(
63                       "QFrame#progressBand {"
64                       "  background: %1;"
65                       "}"
66                       "QLabel {"
67                       "  color: white;"
68                       "  background: transparent;"
69                       "}"
70                       "QProgressBar {"
71                       "  height: 1em;"
72                       "  width: 20em;"
73                       "  border: 0.1em solid white;"
74                       "  border-radius: 0.2em;"
75                       "  color: white;"
76                       "  background: transparent;"
77                       "}"
78                       "QProgressBar::chunk {"
79                       "  width: 0.1em;"
80                       "  background: rgba(255, 255, 255, 50%);"
81                       "}"
82                       )
83                   .arg(QColor(tango_aluminium_4).name()));
84 
85     connect(wsApp, SIGNAL(splashUpdate(register_action_e,const char*)),
86             this, SLOT(splashUpdate(register_action_e,const char*)));
87 }
88 
89 SplashOverlay::~SplashOverlay()
90 {
91     delete so_ui_;
92 }
93 
94 // Useful for debugging on fast machines.
95 #ifdef THROTTLE_STARTUP
96 #include <QThread>
97 class ThrottleThread : public QThread
98 {
99 public:
100     static void msleep(unsigned long msecs)
101     {
102         QThread::msleep(msecs);
103     }
104 };
105 #endif
106 
107 void SplashOverlay::splashUpdate(register_action_e action, const char *message)
108 {
109     QString action_msg = UTF8_HORIZONTAL_ELLIPSIS;
110 
111 #ifdef THROTTLE_STARTUP
112     ThrottleThread::msleep(10);
113 #endif
114 
115     if (last_action_ == action && (elapsed_timer_.elapsed() < info_update_freq_)) {
116         // Nothing to update yet
117         return;
118     }
119 
120     if (last_action_ != action) {
121         register_cur_++;
122     }
123     last_action_ = action;
124 
125     switch(action) {
126     case RA_DISSECTORS:
127         action_msg = tr("Initializing dissectors");
128         break;
129     case RA_LISTENERS:
130         action_msg = tr("Initializing tap listeners");
131         break;
132     case RA_EXTCAP:
133         action_msg = tr("Initializing external capture plugins");
134         break;
135     case RA_REGISTER:
136         action_msg = tr("Registering dissectors");
137         break;
138     case RA_PLUGIN_REGISTER:
139         action_msg = tr("Registering plugins");
140         break;
141     case RA_HANDOFF:
142         action_msg = tr("Handing off dissectors");
143         break;
144     case RA_PLUGIN_HANDOFF:
145         action_msg = tr("Handing off plugins");
146         break;
147     case RA_LUA_PLUGINS:
148         action_msg = tr("Loading Lua plugins");
149         break;
150     case RA_LUA_DEREGISTER:
151         action_msg = tr("Removing Lua plugins");
152         break;
153     case RA_PREFERENCES:
154         action_msg = tr("Loading module preferences");
155         break;
156     case RA_INTERFACES:
157         action_msg = tr("Finding local interfaces");
158         break;
159     default:
160         action_msg = tr("(Unknown action)");
161         break;
162     }
163 
164     if (message) {
165         if (!strncmp(message, "proto_register_", 15))
166             message += 15;
167         else if (!strncmp(message, "proto_reg_handoff_", 18))
168             message += 18;
169         action_msg.append(" ").append(message);
170     }
171     so_ui_->actionLabel->setText(action_msg);
172 
173     so_ui_->progressBar->setValue(register_cur_);
174 
175     wsApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers, 1);
176     elapsed_timer_.restart();
177 }
178