1 // vim: set tabstop=4 shiftwidth=4 expandtab:
2 /*
3 Gwenview: an image viewer
4 Copyright 2008 Aurélien Gâteau <agateau@kde.org>
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA.
19 
20 */
21 // Self
22 #include "fullscreencontent.h"
23 
24 // Qt
25 #include <QAction>
26 #include <QApplication>
27 #include <QCheckBox>
28 #include <QEvent>
29 #include <QLabel>
30 #include <QMenu>
31 #include <QTimer>
32 #include <QToolButton>
33 #include <QWidgetAction>
34 
35 // KF
36 #include <KActionCollection>
37 #include <KActionMenu>
38 #include <KIconLoader>
39 #include <KLocalizedString>
40 
41 // Local
42 #include "gwenview_app_debug.h"
43 #include <gvcore.h>
44 #include <lib/document/documentfactory.h>
45 #include <lib/eventwatcher.h>
46 #include <lib/fullscreenbar.h>
47 #include <lib/gwenviewconfig.h>
48 #include <lib/imagemetainfomodel.h>
49 #include <lib/shadowfilter.h>
50 #include <lib/slideshow.h>
51 #include <lib/stylesheetutils.h>
52 #include <lib/thumbnailview/thumbnailbarview.h>
53 
54 namespace Gwenview
55 {
56 /**
57  * A widget which behaves more or less like a QToolBar, but which uses real
58  * widgets for the toolbar items. We need a real widget to be able to position
59  * the option menu.
60  */
61 class FullScreenToolBar : public QWidget
62 {
63 public:
FullScreenToolBar(QWidget * parent=nullptr)64     explicit FullScreenToolBar(QWidget *parent = nullptr)
65         : QWidget(parent)
66         , mLayout(new QHBoxLayout(this))
67     {
68         setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
69         mLayout->setSpacing(0);
70         mLayout->setContentsMargins(0, 0, 0, 0);
71     }
72 
addAction(QAction * action,Qt::ToolButtonStyle style=Qt::ToolButtonIconOnly)73     void addAction(QAction *action, Qt::ToolButtonStyle style = Qt::ToolButtonIconOnly)
74     {
75         auto *button = new QToolButton;
76         button->setDefaultAction(action);
77         button->setToolButtonStyle(style);
78         button->setAutoRaise(true);
79         const int extent = KIconLoader::SizeMedium;
80         button->setIconSize(QSize(extent, extent));
81         mLayout->addWidget(button);
82     }
83 
addSeparator()84     void addSeparator()
85     {
86         mLayout->addSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
87     }
88 
addStretch()89     void addStretch()
90     {
91         mLayout->addStretch();
92     }
93 
setDirection(QBoxLayout::Direction direction)94     void setDirection(QBoxLayout::Direction direction)
95     {
96         mLayout->setDirection(direction);
97     }
98 
99 private:
100     QBoxLayout *mLayout;
101 };
102 
FullScreenContent(QObject * parent,GvCore * gvCore)103 FullScreenContent::FullScreenContent(QObject *parent, GvCore *gvCore)
104     : QObject(parent)
105 {
106     mGvCore = gvCore;
107     mViewPageVisible = false;
108 }
109 
init(KActionCollection * actionCollection,QWidget * autoHideParentWidget,SlideShow * slideShow)110 void FullScreenContent::init(KActionCollection *actionCollection, QWidget *autoHideParentWidget, SlideShow *slideShow)
111 {
112     mSlideShow = slideShow;
113     mActionCollection = actionCollection;
114     connect(actionCollection->action(QStringLiteral("view")), &QAction::toggled, this, &FullScreenContent::slotViewModeActionToggled);
115 
116     // mAutoHideContainer
117     mAutoHideContainer = new FullScreenBar(autoHideParentWidget);
118     mAutoHideContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
119     auto *layout = new QVBoxLayout(mAutoHideContainer);
120     layout->setContentsMargins(0, 0, 0, 0);
121     layout->setSpacing(0);
122 
123     EventWatcher::install(autoHideParentWidget, QEvent::Resize, this, SLOT(adjustSize()));
124 
125     // mContent
126     mContent = new QWidget;
127     mContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
128     mContent->setAutoFillBackground(true);
129     EventWatcher::install(mContent, QEvent::Show, this, SLOT(updateCurrentUrlWidgets()));
130     layout->addWidget(mContent);
131 
132     createOptionsAction();
133 
134     // mToolBar
135     mToolBar = new FullScreenToolBar(mContent);
136 
137 #define addAction(name) mToolBar->addAction(actionCollection->action(name))
138     addAction("toggle_sidebar");
139     mToolBar->addSeparator();
140     addAction("browse");
141     addAction("view");
142     mToolBar->addSeparator();
143     addAction("go_previous");
144     addAction("toggle_slideshow");
145     addAction("go_next");
146     mToolBar->addSeparator();
147     addAction("rotate_left");
148     addAction("rotate_right");
149 #undef addAction
150     mToolBarShadow = new ShadowFilter(mToolBar);
151 
152     // mInformationLabel
153     mInformationLabel = new QLabel;
154     mInformationLabel->setWordWrap(true);
155     mInformationLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
156 
157     // mDocumentCountLabel
158     mDocumentCountLabel = new QLabel;
159 
160     mInformationContainer = new QWidget;
161     const int infoContainerTopMargin = 6;
162     const int infoContainerBottomMargin = 2;
163     mInformationContainer->setContentsMargins(6, infoContainerTopMargin, 6, infoContainerBottomMargin);
164     mInformationContainer->setAutoFillBackground(true);
165     mInformationContainer->setBackgroundRole(QPalette::Mid);
166     mInformationContainerShadow = new ShadowFilter(mInformationContainer);
167     auto *hLayout = new QHBoxLayout(mInformationContainer);
168     hLayout->setContentsMargins(0, 0, 0, 0);
169     hLayout->addWidget(mInformationLabel);
170     hLayout->addWidget(mDocumentCountLabel);
171 
172     // Thumbnail bar
173     mThumbnailBar = new ThumbnailBarView(mContent);
174     mThumbnailBar->setThumbnailScaleMode(ThumbnailView::ScaleToSquare);
175     auto *delegate = new ThumbnailBarItemDelegate(mThumbnailBar);
176     mThumbnailBar->setItemDelegate(delegate);
177     mThumbnailBar->setSelectionMode(QAbstractItemView::ExtendedSelection);
178     // Calculate minimum bar height to give mInformationLabel exactly two lines height
179     const int lineHeight = mInformationLabel->fontMetrics().lineSpacing();
180     mMinimumThumbnailBarHeight = mToolBar->sizeHint().height() + lineHeight * 2 + infoContainerTopMargin + infoContainerBottomMargin;
181 
182     // Ensure document count is updated when items added/removed from folder
183     connect(mThumbnailBar, &ThumbnailBarView::rowsInsertedSignal, this, &FullScreenContent::updateDocumentCountLabel);
184     connect(mThumbnailBar, &ThumbnailBarView::rowsRemovedSignal, this, &FullScreenContent::updateDocumentCountLabel);
185     connect(mThumbnailBar, &ThumbnailBarView::indexActivated, this, &FullScreenContent::updateDocumentCountLabel);
186 
187     // Right bar
188     mRightToolBar = new FullScreenToolBar(mContent);
189     mRightToolBar->addAction(mActionCollection->action(QStringLiteral("leave_fullscreen")), Qt::ToolButtonFollowStyle);
190     mRightToolBar->addAction(mOptionsAction, Qt::ToolButtonFollowStyle);
191     mRightToolBar->addStretch();
192     mRightToolBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
193     mRightToolBarShadow = new ShadowFilter(mRightToolBar);
194 
195     updateLayout();
196 
197     updateContainerAppearance();
198 }
199 
thumbnailBar() const200 ThumbnailBarView *FullScreenContent::thumbnailBar() const
201 {
202     return mThumbnailBar;
203 }
204 
setCurrentUrl(const QUrl & url)205 void FullScreenContent::setCurrentUrl(const QUrl &url)
206 {
207     if (url.isEmpty()) {
208         mCurrentDocument = Document::Ptr();
209     } else {
210         mCurrentDocument = DocumentFactory::instance()->load(url);
211         connect(mCurrentDocument.data(), &Document::metaInfoUpdated, this, &FullScreenContent::updateCurrentUrlWidgets);
212     }
213     updateCurrentUrlWidgets();
214 
215     // Give the thumbnail view time to update its "current index"
216     QTimer::singleShot(0, this, &FullScreenContent::updateDocumentCountLabel);
217 }
218 
updateInformationLabel()219 void FullScreenContent::updateInformationLabel()
220 {
221     if (!mCurrentDocument) {
222         return;
223     }
224 
225     if (!mInformationLabel->isVisible()) {
226         return;
227     }
228 
229     ImageMetaInfoModel *model = mCurrentDocument->metaInfo();
230 
231     QStringList valueList;
232     const QStringList fullScreenPreferredMetaInfoKeyList = GwenviewConfig::fullScreenPreferredMetaInfoKeyList();
233     for (const QString &key : fullScreenPreferredMetaInfoKeyList) {
234         const QString value = model->getValueForKey(key);
235         if (!value.isEmpty()) {
236             valueList << value;
237         }
238     }
239     QString text = valueList.join(i18nc("@item:intext fullscreen meta info separator", ", "));
240 
241     mInformationLabel->setText(text);
242 }
243 
updateCurrentUrlWidgets()244 void FullScreenContent::updateCurrentUrlWidgets()
245 {
246     updateInformationLabel();
247     updateMetaInfoDialog();
248 }
249 
showImageMetaInfoDialog()250 void FullScreenContent::showImageMetaInfoDialog()
251 {
252     if (!mImageMetaInfoDialog) {
253         mImageMetaInfoDialog = new ImageMetaInfoDialog(mInformationLabel);
254         // Do not let the fullscreen theme propagate to this dialog for now,
255         // it's already quite complicated to create a theme
256         mImageMetaInfoDialog->setStyle(QApplication::style());
257         mImageMetaInfoDialog->setAttribute(Qt::WA_DeleteOnClose, true);
258         connect(mImageMetaInfoDialog.data(),
259                 &ImageMetaInfoDialog::preferredMetaInfoKeyListChanged,
260                 this,
261                 &FullScreenContent::slotPreferredMetaInfoKeyListChanged);
262         connect(mImageMetaInfoDialog.data(), &QObject::destroyed, this, &FullScreenContent::slotImageMetaInfoDialogClosed);
263     }
264     if (mCurrentDocument) {
265         mImageMetaInfoDialog->setMetaInfo(mCurrentDocument->metaInfo(), GwenviewConfig::fullScreenPreferredMetaInfoKeyList());
266     }
267     mAutoHideContainer->setAutoHidingEnabled(false);
268     mImageMetaInfoDialog->show();
269 }
270 
slotPreferredMetaInfoKeyListChanged(const QStringList & list)271 void FullScreenContent::slotPreferredMetaInfoKeyListChanged(const QStringList &list)
272 {
273     GwenviewConfig::setFullScreenPreferredMetaInfoKeyList(list);
274     GwenviewConfig::self()->save();
275     updateInformationLabel();
276 }
277 
updateMetaInfoDialog()278 void FullScreenContent::updateMetaInfoDialog()
279 {
280     if (!mImageMetaInfoDialog) {
281         return;
282     }
283     ImageMetaInfoModel *model = mCurrentDocument ? mCurrentDocument->metaInfo() : nullptr;
284     mImageMetaInfoDialog->setMetaInfo(model, GwenviewConfig::fullScreenPreferredMetaInfoKeyList());
285 }
286 
formatSlideShowIntervalText(int value)287 static QString formatSlideShowIntervalText(int value)
288 {
289     return i18ncp("Slideshow interval in seconds", "%1 sec", "%1 secs", value);
290 }
291 
updateLayout()292 void FullScreenContent::updateLayout()
293 {
294     delete mContent->layout();
295 
296     if (GwenviewConfig::showFullScreenThumbnails()) {
297         mRightToolBar->setDirection(QBoxLayout::TopToBottom);
298 
299         auto *layout = new QHBoxLayout(mContent);
300         layout->setContentsMargins(0, 0, 0, 0);
301         layout->setSpacing(0);
302         QVBoxLayout *vLayout;
303 
304         // First column
305         vLayout = new QVBoxLayout;
306         vLayout->addWidget(mToolBar);
307         vLayout->addWidget(mInformationContainer);
308         layout->addLayout(vLayout);
309         // Second column
310         layout->addSpacing(2);
311         layout->addWidget(mThumbnailBar);
312         layout->addSpacing(2);
313         // Third column
314         vLayout = new QVBoxLayout;
315         vLayout->addWidget(mRightToolBar);
316         layout->addLayout(vLayout);
317 
318         mInformationContainer->setMaximumWidth(mToolBar->sizeHint().width());
319         const int barHeight = qMax(GwenviewConfig::fullScreenBarHeight(), mMinimumThumbnailBarHeight);
320         mThumbnailBar->setFixedHeight(barHeight);
321         mAutoHideContainer->setFixedHeight(barHeight);
322 
323         mInformationLabel->setAlignment(Qt::AlignTop);
324         mDocumentCountLabel->setAlignment(Qt::AlignBottom | Qt::AlignRight);
325 
326         // Shadows
327         mToolBarShadow->reset();
328         mToolBarShadow->setShadow(ShadowFilter::RightEdge, QColor(0, 0, 0, 64));
329         mToolBarShadow->setShadow(ShadowFilter::BottomEdge, QColor(255, 255, 255, 8));
330 
331         mInformationContainerShadow->reset();
332         mInformationContainerShadow->setShadow(ShadowFilter::LeftEdge, QColor(0, 0, 0, 64));
333         mInformationContainerShadow->setShadow(ShadowFilter::TopEdge, QColor(0, 0, 0, 64));
334         mInformationContainerShadow->setShadow(ShadowFilter::RightEdge, QColor(0, 0, 0, 128));
335         mInformationContainerShadow->setShadow(ShadowFilter::BottomEdge, QColor(255, 255, 255, 8));
336 
337         mRightToolBarShadow->reset();
338         mRightToolBarShadow->setShadow(ShadowFilter::LeftEdge, QColor(0, 0, 0, 64));
339         mRightToolBarShadow->setShadow(ShadowFilter::BottomEdge, QColor(255, 255, 255, 8));
340     } else {
341         mRightToolBar->setDirection(QBoxLayout::RightToLeft);
342 
343         auto *layout = new QHBoxLayout(mContent);
344         layout->setContentsMargins(0, 0, 0, 0);
345         layout->setSpacing(0);
346         layout->addWidget(mToolBar);
347         layout->addWidget(mInformationContainer);
348         layout->addWidget(mRightToolBar);
349 
350         mInformationContainer->setMaximumWidth(QWIDGETSIZE_MAX);
351         mAutoHideContainer->setFixedHeight(mToolBar->sizeHint().height());
352 
353         mInformationLabel->setAlignment(Qt::AlignVCenter);
354         mDocumentCountLabel->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
355 
356         // Shadows
357         mToolBarShadow->reset();
358 
359         mInformationContainerShadow->reset();
360         mInformationContainerShadow->setShadow(ShadowFilter::LeftEdge, QColor(0, 0, 0, 64));
361         mInformationContainerShadow->setShadow(ShadowFilter::RightEdge, QColor(0, 0, 0, 32));
362 
363         mRightToolBarShadow->reset();
364         mRightToolBarShadow->setShadow(ShadowFilter::LeftEdge, QColor(255, 255, 255, 8));
365     }
366 }
367 
updateContainerAppearance()368 void FullScreenContent::updateContainerAppearance()
369 {
370     if (!mContent->window()->isFullScreen() || !mViewPageVisible) {
371         mAutoHideContainer->setActivated(false);
372         return;
373     }
374 
375     mThumbnailBar->setVisible(GwenviewConfig::showFullScreenThumbnails());
376     mAutoHideContainer->adjustSize();
377     mAutoHideContainer->setActivated(true);
378 }
379 
adjustSize()380 void FullScreenContent::adjustSize()
381 {
382     if (mContent->window()->isFullScreen() && mViewPageVisible) {
383         mAutoHideContainer->adjustSize();
384     }
385 }
386 
createOptionsAction()387 void FullScreenContent::createOptionsAction()
388 {
389     // We do not use a KActionMenu because:
390     //
391     // - It causes the button to show a small down arrow on its right,
392     // which makes it wider
393     //
394     // - We can't control where the menu shows: in no-thumbnail-mode, the
395     // menu should not be aligned to the right edge of the screen because
396     // if the mode is changed to thumbnail-mode, we want the option button
397     // to remain visible
398     mOptionsAction = new QAction(this);
399     mOptionsAction->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
400     mOptionsAction->setText(i18n("Configure"));
401     mOptionsAction->setToolTip(i18nc("@info:tooltip", "Configure full screen mode"));
402     QObject::connect(mOptionsAction, &QAction::triggered, this, &FullScreenContent::showOptionsMenu);
403 }
404 
updateSlideShowIntervalLabel()405 void FullScreenContent::updateSlideShowIntervalLabel()
406 {
407     Q_ASSERT(mConfigWidget);
408     int value = mConfigWidget->mSlideShowIntervalSlider->value();
409     QString text = formatSlideShowIntervalText(value);
410     mConfigWidget->mSlideShowIntervalLabel->setText(text);
411 }
412 
setFullScreenBarHeight(int value)413 void FullScreenContent::setFullScreenBarHeight(int value)
414 {
415     mThumbnailBar->setFixedHeight(value);
416     mAutoHideContainer->setFixedHeight(value);
417     GwenviewConfig::setFullScreenBarHeight(value);
418 }
419 
showOptionsMenu()420 void FullScreenContent::showOptionsMenu()
421 {
422     Q_ASSERT(!mConfigWidget);
423 
424     mConfigWidget = new FullScreenConfigWidget;
425     FullScreenConfigWidget *widget = mConfigWidget;
426 
427     // Put widget in a menu
428     QMenu menu;
429     auto *action = new QWidgetAction(&menu);
430     action->setDefaultWidget(widget);
431     menu.addAction(action);
432 
433     // Slideshow checkboxes
434     widget->mSlideShowLoopCheckBox->setChecked(mSlideShow->loopAction()->isChecked());
435     connect(widget->mSlideShowLoopCheckBox, &QAbstractButton::toggled, mSlideShow->loopAction(), &QAction::trigger);
436 
437     widget->mSlideShowRandomCheckBox->setChecked(mSlideShow->randomAction()->isChecked());
438     connect(widget->mSlideShowRandomCheckBox, &QAbstractButton::toggled, mSlideShow->randomAction(), &QAction::trigger);
439 
440     // Interval slider
441     widget->mSlideShowIntervalSlider->setValue(int(GwenviewConfig::interval()));
442     connect(widget->mSlideShowIntervalSlider, &QAbstractSlider::valueChanged, mSlideShow, &SlideShow::setInterval);
443     connect(widget->mSlideShowIntervalSlider, &QAbstractSlider::valueChanged, this, &FullScreenContent::updateSlideShowIntervalLabel);
444 
445     // Interval label
446     QString text = formatSlideShowIntervalText(88);
447     int width = widget->mSlideShowIntervalLabel->fontMetrics().boundingRect(text).width();
448     widget->mSlideShowIntervalLabel->setFixedWidth(width);
449     updateSlideShowIntervalLabel();
450 
451     // Image information
452     connect(widget->mConfigureDisplayedInformationButton, &QAbstractButton::clicked, this, &FullScreenContent::showImageMetaInfoDialog);
453 
454     // Thumbnails
455     widget->mThumbnailGroupBox->setVisible(mViewPageVisible);
456     if (mViewPageVisible) {
457         widget->mShowThumbnailsCheckBox->setChecked(GwenviewConfig::showFullScreenThumbnails());
458         widget->mHeightSlider->setMinimum(mMinimumThumbnailBarHeight);
459         widget->mHeightSlider->setValue(mThumbnailBar->height());
460         connect(widget->mShowThumbnailsCheckBox, &QAbstractButton::toggled, this, &FullScreenContent::slotShowThumbnailsToggled);
461         connect(widget->mHeightSlider, &QAbstractSlider::valueChanged, this, &FullScreenContent::setFullScreenBarHeight);
462     }
463 
464     // Show menu below its button
465     QPoint pos;
466     QWidget *button = mOptionsAction->associatedWidgets().constFirst();
467     Q_ASSERT(button);
468     qCWarning(GWENVIEW_APP_LOG) << button << button->geometry();
469     if (QApplication::isRightToLeft()) {
470         pos = button->mapToGlobal(button->rect().bottomLeft());
471     } else {
472         pos = button->mapToGlobal(button->rect().bottomRight());
473         pos.rx() -= menu.sizeHint().width();
474     }
475     qCWarning(GWENVIEW_APP_LOG) << pos;
476     menu.exec(pos);
477 }
478 
setFullScreenMode(bool fullScreenMode)479 void FullScreenContent::setFullScreenMode(bool fullScreenMode)
480 {
481     Q_UNUSED(fullScreenMode);
482     updateContainerAppearance();
483     setupThumbnailBarStyleSheet();
484 }
485 
setDistractionFreeMode(bool distractionFreeMode)486 void FullScreenContent::setDistractionFreeMode(bool distractionFreeMode)
487 {
488     mAutoHideContainer->setEdgeTriggerEnabled(!distractionFreeMode);
489 }
490 
slotImageMetaInfoDialogClosed()491 void FullScreenContent::slotImageMetaInfoDialogClosed()
492 {
493     mAutoHideContainer->setAutoHidingEnabled(true);
494 }
495 
slotShowThumbnailsToggled(bool value)496 void FullScreenContent::slotShowThumbnailsToggled(bool value)
497 {
498     GwenviewConfig::setShowFullScreenThumbnails(value);
499     GwenviewConfig::self()->save();
500     mThumbnailBar->setVisible(value);
501     updateLayout();
502     mContent->adjustSize();
503     mAutoHideContainer->adjustSize();
504 }
505 
slotViewModeActionToggled(bool value)506 void FullScreenContent::slotViewModeActionToggled(bool value)
507 {
508     mViewPageVisible = value;
509     updateContainerAppearance();
510 }
511 
setupThumbnailBarStyleSheet()512 void FullScreenContent::setupThumbnailBarStyleSheet()
513 {
514     const QPalette pal = mGvCore->palette(GvCore::NormalPalette);
515     const QPalette fsPal = mGvCore->palette(GvCore::FullScreenPalette);
516     QColor bgColor = fsPal.color(QPalette::Normal, QPalette::Base);
517     QColor bgSelColor = pal.color(QPalette::Normal, QPalette::Highlight);
518     QColor bgHovColor = pal.color(QPalette::Normal, QPalette::Highlight);
519 
520     // Darken the select color a little to suit dark theme of fullscreen mode
521     bgSelColor.setHsv(bgSelColor.hue(), bgSelColor.saturation(), (bgSelColor.value() * 0.8));
522 
523     // Calculate hover color based on background color in case it changes (matches ViewMainPage thumbnail bar)
524     bgHovColor.setHsv(bgHovColor.hue(), (bgHovColor.saturation() / 2), ((bgHovColor.value() + bgColor.value()) / 2));
525 
526     QString genCss =
527         "QListView {"
528         "  background-color: %1;"
529         "}";
530     genCss = genCss.arg(StyleSheetUtils::rgba(bgColor));
531 
532     QString itemSelCss =
533         "QListView::item:selected {"
534         "  background-color: %1;"
535         "}";
536     itemSelCss = itemSelCss.arg(StyleSheetUtils::rgba(bgSelColor));
537 
538     QString itemHovCss =
539         "QListView::item:hover:!selected {"
540         "  background-color: %1;"
541         "}";
542     itemHovCss = itemHovCss.arg(StyleSheetUtils::rgba(bgHovColor));
543 
544     QString css = genCss + itemSelCss + itemHovCss;
545     mThumbnailBar->setStyleSheet(css);
546 }
547 
updateDocumentCountLabel()548 void FullScreenContent::updateDocumentCountLabel()
549 {
550     const int current = mThumbnailBar->currentIndex().row() + 1;
551     const int total = mThumbnailBar->model()->rowCount();
552     const QString text = i18nc("@info:status %1 current document index, %2 total documents", "%1 of %2", current, total);
553     mDocumentCountLabel->setText(text);
554 }
555 
556 } // namespace
557