Bug Summary

File:builds/wireshark/wireshark/ui/qt/welcome_page.cpp
Warning:line 325, column 10
Value stored to 'collapseLinks' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name welcome_page.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /builds/wireshark/wireshark/ui/qt/lua_debugger -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore5Compat -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6/QtSvg -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE5COMPAT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_SVG_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=c++17 -fdeprecated-macro -ferror-limit 19 -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-05-29-100335-3678-1 -x c++ /builds/wireshark/wireshark/ui/qt/welcome_page.cpp
1/* welcome_page.cpp
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <[email protected]>
5 * Copyright 1998 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include "config.h"
11
12#include <epan/prefs.h>
13
14#include "ui/recent.h"
15#include "ui/urls.h"
16
17#include <app/application_flavor.h>
18
19#include "welcome_page.h"
20#include <ui_welcome_page.h>
21#include <ui/qt/utils/tango_colors.h>
22#include <ui/qt/utils/color_utils.h>
23#include <ui/qt/utils/qt_ui_utils.h>
24#include <ui/qt/models/recentcapturefiles_list_model.h>
25#include <ui/qt/utils/workspace_state.h>
26#include <ui/qt/widgets/capture_card_widget.h>
27
28#include "main_application.h"
29
30#include <QClipboard>
31#include <QDesktopServices>
32#include <QDir>
33#include <QListWidget>
34#include <QMenu>
35#include <QResizeEvent>
36#include <QUrl>
37#include <QWidget>
38
39#ifndef VERSION_FLAVOR"Development Build"
40#define VERSION_FLAVOR"Development Build" ""
41#endif
42
43WelcomePage::WelcomePage(QWidget *parent) :
44 QFrame(parent),
45 welcome_ui_(new Ui::WelcomePage),
46 #ifdef Q_OS_MAC
47 show_in_str_(tr("Show in Finder")),
48 #else
49 show_in_str_(tr("Show in Folder")),
50 #endif
51 splash_overlay_(NULL__null)
52
53{
54 welcome_ui_->setupUi(this);
55
56 setContentsMargins(0, 0, 0, 0);
57 setAccessibleName(tr("Welcome page"));
58 setAccessibleDescription(tr("The %1 welcome page provides access to recent files, capture interfaces, and learning resources.").arg(mainApp->applicationName()));
59
60 /* Initially set the sidebar hidden, it will be made visible or not by
61 * applySidebarPreferences. */
62 welcome_ui_->sidebarContainer->setVisible(false);
63
64 updateStyleSheets();
65
66 /* Handle Recent Capture Files List */
67 // In welcome_page.cpp or wherever the list is created
68 auto *model = new RecentCaptureFilesListModel(this);
69 auto *proxyModel = new RecentCaptureFilesReverseProxyModel(this);
70 proxyModel->setSourceModel(model);
71
72 welcome_ui_->openFileSectionRecentList->setVisible(true);
73 welcome_ui_->openFileSectionRecentList->setModel(proxyModel);
74 welcome_ui_->openFileSectionRecentList->setItemDelegate(new RecentCaptureFilesDelegate(welcome_ui_->openFileSectionRecentList));
75 welcome_ui_->openFileSectionRecentList->setContextMenuPolicy(Qt::CustomContextMenu);
76 welcome_ui_->openFileSectionRecentList->setAccessibleName(tr("Recent capture files"));
77 welcome_ui_->openFileSectionRecentList->setAccessibleDescription(tr("List of recently opened capture files. Double-click or press Enter to open."));
78 connect(welcome_ui_->openFileSectionRecentList, &QListView::activated,
79 this, [this]() {
80 QModelIndex index = welcome_ui_->openFileSectionRecentList->currentIndex();
81 if (index.isValid()) {
82 QString cfile = index.data(RecentCaptureFilesListModel::FilenameRole).toString();
83 emit recentFileActivated(cfile);
84 }
85 });
86 connect(welcome_ui_->openFileSectionRecentList, &QListView::customContextMenuRequested,
87 this, &WelcomePage::showCaptureFilesContextMenu);
88
89 if (WorkspaceState::instance()->recentCaptureFiles().size() > 0) {
90 welcome_ui_->openFileSectionLabel->setVisible(true);
91 welcome_ui_->openFileSectionRecentList->setVisible(true);
92 } else {
93 welcome_ui_->openFileSectionLabel->setVisible(false);
94 welcome_ui_->openFileSectionRecentList->setVisible(false);
95 }
96
97#ifdef Q_OS_MAC
98 welcome_ui_->openFileSectionRecentList->setAttribute(Qt::WA_MacShowFocusRect, false);
99#endif
100
101 welcome_ui_->openFileSectionRecentList->setTextElideMode(Qt::ElideLeft);
102
103 connect(mainApp, &MainApplication::appInitialized, this, &WelcomePage::appInitialized);
104 connect(mainApp, &MainApplication::preferencesChanged, this, &WelcomePage::applySidebarPreferences);
105
106 // "Capture" header click opens Capture Options dialog
107 if (auto *captureHeader = welcome_ui_->captureSectionCard->findChild<ClickableLabel*>(QStringLiteral("captureHeader")(QString(QtPrivate::qMakeStringPrivate(u"" "captureHeader"))))) {
108 connect(captureHeader, &ClickableLabel::clicked, this, []() {
109 mainApp->doTriggerMenuItem(MainApplication::CaptureOptionsDialog);
110 });
111 }
112
113 splash_overlay_ = new SplashOverlay(this);
114}
115
116WelcomePage::~WelcomePage()
117{
118 delete welcome_ui_;
119}
120
121InterfaceFrame *WelcomePage::getInterfaceFrame()
122{
123 return welcome_ui_->captureSectionCard->interfaceFrame();
124}
125
126CaptureCardWidget *WelcomePage::captureCard()
127{
128 return welcome_ui_->captureSectionCard;
129}
130
131const QString WelcomePage::captureFilter()
132{
133 return welcome_ui_->captureSectionCard->captureFilter();
134}
135
136void WelcomePage::setCaptureFilter(const QString capture_filter)
137{
138 welcome_ui_->captureSectionCard->setCaptureFilter(capture_filter);
139}
140
141void WelcomePage::setCaptureFilterText(const QString capture_filter)
142{
143 welcome_ui_->captureSectionCard->setCaptureFilterText(capture_filter);
144}
145
146void WelcomePage::interfaceSelected()
147{
148 welcome_ui_->captureSectionCard->interfaceSelected();
149}
150
151void WelcomePage::appInitialized()
152{
153 applySidebarPreferences();
154
155 splash_overlay_->fadeOut();
156 splash_overlay_ = NULL__null;
157
158 // Ensure sidebar layout adapts to the restored window size.
159 // resizeEvent may have fired before the layout was finalized.
160 updateSidebarLayout();
161}
162
163void WelcomePage::applySidebarPreferences()
164{
165 // There are slides that will be shown EVEN if the section card is set hidden through the preferences.
166 // hasVisibleSlides() checks if there are any slides that should be shown, as well as the user's preferences.
167 bool slidesAreVisible = welcome_ui_->tipsSectionCard->hasVisibleSlides();
168
169 welcome_ui_->tipsSectionCard->setSlideDeckFreeze(true);
170 welcome_ui_->tipsSectionCard->setSlideTypeVisible(BannerEvents, recent.gui_welcome_page_sidebar_tips_events);
171 welcome_ui_->tipsSectionCard->setSlideTypeVisible(BannerSponsorship, recent.gui_welcome_page_sidebar_tips_sponsorship);
172 welcome_ui_->tipsSectionCard->setSlideTypeVisible(BannerTips, recent.gui_welcome_page_sidebar_tips_tips);
173 welcome_ui_->tipsSectionCard->setSlidesTest(recent.gui_welcome_page_sidebar_tips_slides_test);
174 welcome_ui_->tipsSectionCard->setSlideDeckFreeze(false);
175 welcome_ui_->tipsSectionCard->setAutoAdvance(recent.gui_welcome_page_sidebar_tips_auto_advance);
176 welcome_ui_->tipsSectionCard->setAutoAdvanceInterval(recent.gui_welcome_page_sidebar_tips_interval);
177 welcome_ui_->tipsSectionCard->setVisible(slidesAreVisible);
178
179 welcome_ui_->learnSectionCard->setVisible(recent.gui_welcome_page_sidebar_learn_visible);
180
181 // Hide the entire sidebar container when all sidebar widgets are disabled,
182 // so the main content area can expand to fill the full window width.
183 bool sidebar_visible = slidesAreVisible || recent.gui_welcome_page_sidebar_learn_visible;
184 welcome_ui_->sidebarContainer->setVisible(sidebar_visible);
185
186 // Ensure sidebar layout adapts to the restored window size.
187 // (XXX - This really only needs to happen if one of the cards is switching
188 // to visibile, and only if this is the first time being shown or if a
189 // ResizeEvent occurred while hidden. But preference changes should be
190 // rare.)
191 updateSidebarLayout();
192}
193
194bool WelcomePage::event(QEvent *event)
195{
196 switch (event->type()) {
197 case QEvent::ApplicationPaletteChange:
198 {
199 updateStyleSheets();
200 break;
201 }
202 case QEvent::LanguageChange:
203 {
204 welcome_ui_->retranslateUi(this);
205 break;
206 }
207 default:
208 break;
209
210 }
211 return QFrame::event(event);
212}
213
214void WelcomePage::resizeEvent(QResizeEvent *event)
215{
216 if (splash_overlay_)
217 splash_overlay_->resize(event->size());
218
219 QFrame::resizeEvent(event);
220
221 updateSidebarLayout();
222}
223
224void WelcomePage::showEvent(QShowEvent *event)
225{
226 QFrame::showEvent(event);
227
228 // The final window geometry may not be known until the widget is shown
229 // (especially on macOS with restored window positions). Ensure the
230 // sidebar layout adapts to the actual available space.
231 updateSidebarLayout();
232}
233
234/*
235 * Adapts the sidebar widget states to the available vertical space.
236 *
237 * The sidebar contains two widgets stacked vertically with spacing between
238 * them: the InfoBannerWidget (tips/sponsors) and the LearnCardWidget (docs
239 * links + action buttons). Both support a compact mode to reduce their
240 * height when the window is small.
241 *
242 * Collapse order (as the window shrinks):
243 * 1. LearnCardWidget links collapse (vertical list -> horizontal row)
244 * 2. InfoBannerWidget compacts (hides illustration and body text)
245 *
246 * Expand order (as the window grows) is the reverse:
247 * 1. InfoBannerWidget expands back to full
248 * 2. LearnCardWidget links expand back to vertical
249 *
250 * All size values are queried from the widgets and layout, not hardcoded:
251 * - tipsFull: InfoBannerWidget::sizeHint().height()
252 * Always returns the full preferred height (360) regardless
253 * of compact state. This is stable because sizeHint()
254 * reports what the widget *wants*, while compact mode is
255 * enforced via setMaximumHeight().
256 * - learnMax: LearnCardWidget::maximumHeight() (from .ui: 240)
257 * - learnMin: LearnCardWidget::minimumHeight() (from .ui: 110)
258 * - spacing: sidebarLayout->spacing() (from .ui: 16)
259 *
260 * Hysteresis (kHysteresis = 20px):
261 * Without hysteresis, at the exact collapse threshold the layout
262 * oscillates: collapsing a widget frees space, which satisfies the
263 * expand threshold, which expands, which exceeds the threshold again.
264 * On each resize event this cycle repeats, causing visible flickering.
265 *
266 * Hysteresis adds a dead zone between collapse and expand thresholds.
267 * A widget collapses at threshold T but only re-expands at T + 20.
268 * In the 20px gap, the current state is preserved.
269 *
270 * The value 20px was chosen empirically: it must be large enough that
271 * the layout geometry change from collapsing/expanding a widget (which
272 * can shift available height by a few pixels due to rounding, spacing,
273 * and platform differences) doesn't cross back over the threshold. In
274 * practice, resize events during a user drag arrive ~8-12px apart, so
275 * 20px ensures at least one stable frame at the boundary. A larger
276 * value would delay the transition visibly; a smaller one risks not
277 * fully suppressing the oscillation on high-DPI displays where pixel
278 * increments are coarser.
279 *
280 * Decision zones (with current widget sizes):
281 *
282 * available >= 636 (linksExpandAt)
283 * -> full tips + expanded links
284 *
285 * available >= 506 (tipsExpandAt) and < 636
286 * -> full tips + collapsed links
287 * (between 616-635: hysteresis zone for links -- keeps current state
288 * if already expanded, won't re-expand if collapsed)
289 *
290 * available >= 486 (tipsCompactAt) and < 506
291 * -> hysteresis zone for tips -- keeps current tips state,
292 * links forced collapsed
293 *
294 * available < 486 (tipsCompactAt)
295 * -> compact tips + collapsed links
296 *
297 * Called from: resizeEvent(), showEvent(), appInitialized(), and
298 * indirectly via updateGeometry() when the welcome header banner
299 * visibility changes.
300 */
301void WelcomePage::updateSidebarLayout()
302{
303 int available = welcome_ui_->sidebarContainer->height();
304 if (available <= 0)
305 return;
306
307 static const int kHysteresis = 20;
308
309 int spacing = welcome_ui_->sidebarLayout->spacing();
310 int tipsFull = welcome_ui_->tipsSectionCard->sizeHint().height();
311 int learnMax = welcome_ui_->learnSectionCard->maximumHeight();
312 int learnMin = welcome_ui_->learnSectionCard->minimumHeight();
313
314 // Collapse threshold: the minimum available height to show this state.
315 // Expand threshold: collapse + hysteresis -- prevents oscillation.
316
317 // Level 1: links collapse when full tips + expanded learn don't fit.
318 int linksCollapseAt = tipsFull + spacing + learnMax;
319 int linksExpandAt = linksCollapseAt + kHysteresis;
320
321 // Level 2: tips compact when full tips + collapsed learn don't fit.
322 int tipsCompactAt = tipsFull + spacing + learnMin;
323 int tipsExpandAt = tipsCompactAt + kHysteresis;
324
325 bool collapseLinks = welcome_ui_->learnSectionCard->isLinksCollapsed();
Value stored to 'collapseLinks' during its initialization is never read
326 bool compactTips = welcome_ui_->tipsSectionCard->isCompactMode();
327
328 if (available >= linksExpandAt) {
329 collapseLinks = false;
330 compactTips = false;
331 } else if (available >= tipsExpandAt) {
332 collapseLinks = true;
333 compactTips = false;
334 } else if (available >= tipsCompactAt) {
335 collapseLinks = true;
336 // tips state preserved (hysteresis zone)
337 } else {
338 collapseLinks = true;
339 compactTips = true;
340 }
341
342 welcome_ui_->learnSectionCard->setLinksCollapsed(collapseLinks);
343 welcome_ui_->tipsSectionCard->setCompactMode(compactTips);
344}
345
346void WelcomePage::showCaptureFilesContextMenu(QPoint pos)
347{
348 QModelIndex index = welcome_ui_->openFileSectionRecentList->indexAt(pos);
349 if (!index.isValid()) return;
350
351 QMenu *recent_ctx_menu = new QMenu(this);
352 recent_ctx_menu->setAttribute(Qt::WA_DeleteOnClose);
353
354 QModelIndex sourceIndex = static_cast<QSortFilterProxyModel*>(welcome_ui_->openFileSectionRecentList->model())->mapToSource(index);
355 RecentCaptureFilesListModel *model = static_cast<RecentCaptureFilesListModel*>(
356 static_cast<QSortFilterProxyModel*>(welcome_ui_->openFileSectionRecentList->model())->sourceModel());
357
358 QString filePath = model->data(sourceIndex, RecentCaptureFilesListModel::FilenameRole).toString();
359 bool accessible = model->data(sourceIndex, RecentCaptureFilesListModel::AccessibleRole).toBool();
360
361 QAction *show_action = recent_ctx_menu->addAction(show_in_str_);
362 show_action->setEnabled(accessible);
363 connect(show_action, &QAction::triggered, this, [filePath]{ desktop_show_in_folder(filePath); });
364
365 QAction *copy_action = recent_ctx_menu->addAction(tr("Copy file path"));
366 connect(copy_action, &QAction::triggered, this, [filePath]{ mainApp->clipboard()->setText(filePath); });
367
368 recent_ctx_menu->addSeparator();
369
370 QAction *remove_action = recent_ctx_menu->addAction(tr("Remove from list"));
371 connect(remove_action, &QAction::triggered, this, [filePath]{
372 WorkspaceState::instance()->removeRecentCaptureFile(filePath);
373 });
374
375 recent_ctx_menu->popup(welcome_ui_->openFileSectionRecentList->viewport()->mapToGlobal(pos));
376}
377
378void WelcomePage::updateStyleSheets()
379{
380 QString welcome_ss = QStringLiteral((QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
381 "WelcomePage {"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
382 " padding: 0;"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
383 " }"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
384 "WelcomePage, QAbstractItemView {"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
385 " background-color: palette(base);"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
386 " color: palette(text);"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
387 " }"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
388 "QAbstractItemView {"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
389 " border: 0;"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
390 "}"(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
391 )(QString(QtPrivate::qMakeStringPrivate(u"" "WelcomePage {" " padding: 0;"
" }" "WelcomePage, QAbstractItemView {" " background-color: palette(base);"
" color: palette(text);" " }" "QAbstractItemView {" " border: 0;"
"}")))
;
392#if !defined(Q_OS_WIN)
393 welcome_ss += QStringLiteral((QString(QtPrivate::qMakeStringPrivate(u"" "QAbstractItemView:item:hover {"
" background-color: %1;" " color: palette(text);" "}")))
394 "QAbstractItemView:item:hover {"(QString(QtPrivate::qMakeStringPrivate(u"" "QAbstractItemView:item:hover {"
" background-color: %1;" " color: palette(text);" "}")))
395 " background-color: %1;"(QString(QtPrivate::qMakeStringPrivate(u"" "QAbstractItemView:item:hover {"
" background-color: %1;" " color: palette(text);" "}")))
396 " color: palette(text);"(QString(QtPrivate::qMakeStringPrivate(u"" "QAbstractItemView:item:hover {"
" background-color: %1;" " color: palette(text);" "}")))
397 "}"(QString(QtPrivate::qMakeStringPrivate(u"" "QAbstractItemView:item:hover {"
" background-color: %1;" " color: palette(text);" "}")))
398 )(QString(QtPrivate::qMakeStringPrivate(u"" "QAbstractItemView:item:hover {"
" background-color: %1;" " color: palette(text);" "}")))
399 .arg(ColorUtils::hoverBackground().name(QColor::HexArgb));
400#endif
401 setStyleSheet(welcome_ss);
402
403 QString title_button_ss = QStringLiteral((QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
404 "QLabel {"(QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
405 " color: %1;"(QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
406 "}"(QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
407 "QLabel::hover {"(QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
408 " color: %2;"(QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
409 "}"(QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
410 )(QString(QtPrivate::qMakeStringPrivate(u"" "QLabel {" " color: %1;"
"}" "QLabel::hover {" " color: %2;" "}")))
411 .arg(QColor(tango_aluminium_4).name()) // Text color
412 .arg(QColor(tango_sky_blue_4).name()); // Hover color
413
414 welcome_ui_->openFileSectionLabel->setStyleSheet(title_button_ss);
415
416 welcome_ui_->openFileSectionRecentList->setStyleSheet(
417 "QListView::item {"
418 " padding-top: 0.2em;"
419 " padding-bottom: 0.2em;"
420 "}"
421 "QListView::item::first {"
422 " padding-top: 0;"
423 "}"
424 "QListView::item::last {"
425 " padding-bottom: 0;"
426 "}"
427 );
428
429 /* LearnCardWidget and CaptureCardWidget manage their own stylesheets */
430}
431
432void WelcomePage::on_openFileSectionLabel_clicked()
433{
434 mainApp->doTriggerMenuItem(MainApplication::FileOpenDialog);
435}