File indexing completed on 2024-04-21 05:54:05
0001 /* 0002 SPDX-FileCopyrightText: 2005-2006, 2010 Tom Albers <toma@kde.org> 0003 SPDX-FileCopyrightText: 2006 Bram Schoenmakers <bramschoenmakers@kde.nl> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "slideshoweffect.h" 0009 #include "breakbase.h" 0010 0011 #include <QApplication> 0012 #include <QDebug> 0013 #include <QDir> 0014 #include <QLabel> 0015 #include <QRandomGenerator> 0016 #include <QScreen> 0017 #include <QTimer> 0018 #include <QVBoxLayout> 0019 0020 #include <KWindowSystem> 0021 0022 SlideEffect::SlideEffect(QObject *parent) 0023 : BreakBase(parent) 0024 , m_searchRecursive(false) 0025 , m_showSmallImages(false) 0026 { 0027 // Make all other screens gray... 0028 slotGray(); 0029 connect(qApp, &QGuiApplication::screenAdded, this, &SlideEffect::slotGray); 0030 connect(qApp, &QGuiApplication::screenRemoved, this, &SlideEffect::slotGray); 0031 0032 m_slidewidget = new SlideWidget(nullptr); 0033 KWindowSystem::forceActiveWindow(m_slidewidget->winId()); 0034 KWindowSystem::setOnAllDesktops(m_slidewidget->winId(), true); 0035 KWindowSystem::setState(m_slidewidget->winId(), NET::KeepAbove); 0036 KWindowSystem::setState(m_slidewidget->winId(), NET::FullScreen); 0037 0038 setReadOnly(true); 0039 0040 m_timer_slide = new QTimer(this); 0041 connect(m_timer_slide, &QTimer::timeout, this, &SlideEffect::slotNewSlide); 0042 } 0043 0044 SlideEffect::~SlideEffect() 0045 { 0046 delete m_slidewidget; 0047 } 0048 0049 void SlideEffect::slotGray() 0050 { 0051 // Make all other screens gray... 0052 setGrayEffectOnAllScreens(true); 0053 excludeGrayEffectOnScreen(QGuiApplication::primaryScreen()); 0054 } 0055 0056 bool SlideEffect::hasImages() 0057 { 0058 return m_files.count() > 0; 0059 } 0060 0061 void SlideEffect::activate() 0062 { 0063 m_slidewidget->show(); 0064 m_timer_slide->start(m_slideInterval * 1000); 0065 BreakBase::activate(); 0066 } 0067 0068 void SlideEffect::deactivate() 0069 { 0070 m_timer_slide->stop(); 0071 m_slidewidget->hide(); 0072 BreakBase::deactivate(); 0073 } 0074 0075 void SlideEffect::loadImage() 0076 { 0077 if (m_files.count() == 0) 0078 return; 0079 0080 // Base the size on the size of the screen, for xinerama. 0081 const QSize size = QGuiApplication::primaryScreen()->geometry().size(); 0082 0083 // Do not accept images whose surface is more than 3 times smaller than 0084 // screen 0085 int min_image_surface = size.width() * size.height() / 3; 0086 QImage image; 0087 0088 while (true) { 0089 // reset if all images are shown 0090 if (m_files_done.count() == m_files.count()) 0091 m_files_done.clear(); 0092 0093 // get a not yet used image 0094 int j; 0095 QString name; 0096 do { 0097 j = QRandomGenerator::global()->bounded(m_files.count()); 0098 name = m_files[j]; 0099 } while (m_files_done.indexOf(name) != -1); 0100 0101 // load image 0102 qDebug() << "Loading:" << name << "(" << j << "/" << m_files.count() << ") "; 0103 image.load(name); 0104 0105 // Check size 0106 if (image.width() * image.height() >= min_image_surface || m_showSmallImages) { 0107 // Image is big enough, leave while loop 0108 m_files_done.append(name); 0109 break; 0110 } else { 0111 // Too small, remove from list 0112 m_files.removeAll(name); 0113 if (m_files.count() == 0) { 0114 // Couldn't find any image big enough, leave function 0115 return; 0116 } 0117 } 0118 } 0119 0120 const Qt::AspectRatioMode mode = (m_expandImageToFullScreen) ? Qt::KeepAspectRatioByExpanding : Qt::KeepAspectRatio; 0121 const QImage m(image.scaled(size.width(), size.height(), mode)); 0122 0123 if (m.isNull()) 0124 return; 0125 0126 m_slidewidget->setImage(m); 0127 } 0128 0129 void SlideEffect::findImagesInFolder(const QString &folder) 0130 { 0131 if (folder.isNull()) 0132 return; 0133 0134 QDir dir(folder); 0135 0136 if (!dir.exists() || !dir.isReadable()) { 0137 qWarning() << "Folder does not exist or is not readable: " << folder; 0138 return; 0139 } 0140 0141 // TODO: make an automated filter, maybe with QImageIO. 0142 QStringList filters; 0143 filters << "*.png" 0144 << "*.jpg" 0145 << "*.jpeg" 0146 << "*.tif" 0147 << "*.tiff" 0148 << "*.gif" 0149 << "*.bmp" 0150 << "*.xpm" 0151 << "*.ppm" 0152 << "*.pnm" 0153 << "*.xcf" 0154 << "*.pcx"; 0155 QStringList filtersUp; 0156 for (int i = 0; i < filters.size(); ++i) 0157 filtersUp << filters.at(i).toUpper(); 0158 dir.setNameFilters(filters << filtersUp); 0159 dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks | QDir::AllDirs); 0160 0161 const QFileInfoList list = dir.entryInfoList(); 0162 for (int i = 0; i < list.count(); ++i) { 0163 QFileInfo fi = list.at(i); 0164 if (fi.isFile()) 0165 m_files.append(fi.filePath()); 0166 else if (fi.isDir() && m_searchRecursive && fi.fileName() != "." && fi.fileName() != "..") 0167 findImagesInFolder(fi.absoluteFilePath()); 0168 } 0169 } 0170 0171 void SlideEffect::slotNewSlide() 0172 { 0173 if (m_files.count() == 1) 0174 return; 0175 0176 loadImage(); 0177 } 0178 0179 void SlideEffect::reset(const QString &path, bool recursive, bool showSmallImages, bool expandImageToFullScreen, int slideInterval) 0180 { 0181 m_files.clear(); 0182 m_files_done.clear(); 0183 m_basePath = path; 0184 m_searchRecursive = recursive; 0185 m_showSmallImages = showSmallImages; 0186 m_slideInterval = slideInterval; 0187 m_expandImageToFullScreen = expandImageToFullScreen; 0188 0189 findImagesInFolder(path); 0190 qDebug() << "Amount of Files:" << m_files.count(); 0191 QTimer::singleShot(2000, this, &SlideEffect::slotNewSlide); 0192 } 0193 0194 // ------------------ Show widget 0195 0196 SlideWidget::SlideWidget(QWidget *parent) 0197 : QWidget(parent, Qt::Popup) 0198 { 0199 slotDimension(); 0200 connect(qApp, &QGuiApplication::screenAdded, this, &SlideWidget::slotDimension); 0201 connect(qApp, &QGuiApplication::screenRemoved, this, &SlideWidget::slotDimension); 0202 0203 QVBoxLayout *boxLayout = new QVBoxLayout(this); 0204 boxLayout->setSpacing(0); 0205 boxLayout->setContentsMargins(0, 0, 0, 0); 0206 setLayout(boxLayout); 0207 m_imageLabel = new QLabel(); 0208 m_imageLabel->setMaximumSize(width(), height()); 0209 m_imageLabel->setAlignment(Qt::AlignCenter); 0210 layout()->addWidget(m_imageLabel); 0211 } 0212 0213 SlideWidget::~SlideWidget() 0214 { 0215 } 0216 0217 void SlideWidget::slotDimension() 0218 { 0219 const QRect rect = QGuiApplication::primaryScreen()->geometry(); 0220 setGeometry(rect); 0221 } 0222 0223 void SlideWidget::setImage(const QImage &image) 0224 { 0225 m_imageLabel->setPixmap(QPixmap::fromImage(image)); 0226 }