File indexing completed on 2025-01-19 03:55:43

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-12-23
0007  * Description : a widget to manage preview.
0008  *
0009  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2012      by Benjamin Girault <benjamin dot girault at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "dpreviewmanager.h"
0017 
0018 // Qt includes
0019 
0020 #include <QStyle>
0021 #include <QLabel>
0022 #include <QTimer>
0023 #include <QPixmap>
0024 #include <QPushButton>
0025 #include <QVBoxLayout>
0026 #include <QHBoxLayout>
0027 #include <QFrame>
0028 
0029 // KDE includes
0030 
0031 #include <klocalizedstring.h>
0032 
0033 // Local includes
0034 
0035 #include "dpreviewimage.h"
0036 #include "dlayoutbox.h"
0037 #include "dworkingpixmap.h"
0038 
0039 namespace Digikam
0040 {
0041 
0042 class Q_DECL_HIDDEN DPreviewManager::Private
0043 {
0044 public:
0045 
0046     explicit Private()
0047       : busy            (false),
0048         textLabel       (nullptr),
0049         thumbLabel      (nullptr),
0050         button          (nullptr),
0051         progressCount   (0),
0052         progressPix     (nullptr),
0053         progressTimer   (nullptr),
0054         progressLabel   (nullptr),
0055         preview         (nullptr)
0056     {
0057     }
0058 
0059     bool            busy;
0060 
0061     QLabel*         textLabel;
0062     QLabel*         thumbLabel;
0063 
0064     QPushButton*    button;
0065 
0066     int             progressCount;
0067     DWorkingPixmap* progressPix;
0068     QTimer*         progressTimer;
0069     QLabel*         progressLabel;
0070 
0071     DPreviewImage* preview;
0072 };
0073 
0074 DPreviewManager::DPreviewManager(QWidget* const parent)
0075     : QStackedWidget(parent),
0076       d             (new Private)
0077 {
0078     setAttribute(Qt::WA_DeleteOnClose);
0079     setMinimumSize(QSize(400, 300));
0080     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0081 
0082     d->progressPix             = new DWorkingPixmap(this);
0083 
0084     QFrame* const vbox         = new QFrame(this);
0085     QVBoxLayout* const vboxLay = new QVBoxLayout(vbox);
0086     vbox->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
0087     vbox->setLineWidth( style()->pixelMetric(QStyle::PM_DefaultFrameWidth) );
0088     QLabel* const space1       = new QLabel(vbox);
0089     d->progressLabel           = new QLabel(vbox);
0090     d->progressLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
0091     QLabel* const space2       = new QLabel(vbox);
0092     d->thumbLabel              = new QLabel(vbox);
0093     d->thumbLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
0094     QLabel* const space3       = new QLabel(vbox);
0095     d->textLabel               = new QLabel(vbox);
0096     d->textLabel->setScaledContents(true);
0097     d->textLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
0098 
0099     QWidget* const hbox        = new QWidget(vbox);
0100     QHBoxLayout* const hboxLay = new QHBoxLayout(hbox);
0101     QLabel* const space4       = new QLabel(hbox);
0102     d->button                  = new QPushButton(hbox);
0103     d->button->hide();
0104     QLabel* const space5       = new QLabel(hbox);
0105 
0106     hboxLay->addWidget(space4);
0107     hboxLay->addWidget(d->button);
0108     hboxLay->addWidget(space5);
0109     hboxLay->setStretchFactor(space4, 10);
0110     hboxLay->setStretchFactor(space5, 10);
0111 
0112     QLabel* const space6       = new QLabel(vbox);
0113 
0114     vboxLay->addWidget(space1);
0115     vboxLay->addWidget(d->progressLabel);
0116     vboxLay->addWidget(space2);
0117     vboxLay->addWidget(d->thumbLabel);
0118     vboxLay->addWidget(space3);
0119     vboxLay->addWidget(d->textLabel);
0120     vboxLay->addWidget(hbox);
0121     vboxLay->addWidget(space6);
0122     vboxLay->setStretchFactor(space1, 10);
0123     vboxLay->setStretchFactor(d->progressLabel, 5);
0124     vboxLay->setStretchFactor(space2, 1);
0125     vboxLay->setStretchFactor(d->thumbLabel, 5);
0126     vboxLay->setStretchFactor(space3, 1);
0127     vboxLay->setStretchFactor(d->textLabel, 5);
0128     vboxLay->setStretchFactor(space3, 1);
0129     vboxLay->setStretchFactor(hbox, 5);
0130     vboxLay->setStretchFactor(space6, 10);
0131 
0132     d->preview                 = new DPreviewImage(this);
0133 
0134     insertWidget(MessageMode, vbox);
0135     insertWidget(PreviewMode, d->preview);
0136 
0137     d->progressTimer           = new QTimer(this);
0138 
0139     connect(d->progressTimer, &QTimer::timeout,
0140             this, &DPreviewManager::slotProgressTimerDone);
0141 
0142     connect(d->button, &QPushButton::clicked,
0143             this, &DPreviewManager::signalButtonClicked);
0144 }
0145 
0146 DPreviewManager::~DPreviewManager()
0147 {
0148     delete d;
0149 }
0150 
0151 void DPreviewManager::slotLoad(const QUrl& url)
0152 {
0153     load(url);
0154 }
0155 
0156 void DPreviewManager::setImage(const QImage& img, bool fit)
0157 {
0158     setBusy(false);
0159 
0160     if (!d->preview->setImage(img))
0161     {
0162         setText(i18nc("@info", "Failed to load image"));
0163         return;
0164     }
0165 
0166     setCurrentIndex(PreviewMode);
0167 
0168     if (fit)
0169     {
0170         d->preview->slotZoom2Fit();
0171     }
0172 }
0173 
0174 bool DPreviewManager::load(const QUrl& file, bool fit)
0175 {
0176     setBusy(false);
0177 
0178     if (!d->preview->load(file))
0179     {
0180         setText(i18nc("@info", "Failed to load image"));
0181         return false;
0182     }
0183 
0184     setCurrentIndex(PreviewMode);
0185 
0186     if (fit)
0187     {
0188         d->preview->slotZoom2Fit();
0189     }
0190 
0191     return true;
0192 }
0193 
0194 void DPreviewManager::setThumbnail(const QPixmap& thumbnail)
0195 {
0196     d->thumbLabel->setPixmap(thumbnail);
0197     setCurrentIndex(MessageMode);
0198 }
0199 
0200 void DPreviewManager::setButtonText(const QString& text)
0201 {
0202     d->button->setText(text);
0203 }
0204 
0205 void DPreviewManager::setButtonVisible(bool b)
0206 {
0207     d->button->setVisible(b);
0208 }
0209 
0210 void DPreviewManager::setSelectionAreaPossible(bool b)
0211 {
0212     d->preview->enableSelectionArea(b);
0213 }
0214 
0215 QRectF DPreviewManager::getSelectionArea() const
0216 {
0217     return d->preview->getSelectionArea();
0218 }
0219 
0220 void DPreviewManager::setSelectionArea(const QRectF& rectangle)
0221 {
0222     d->preview->setSelectionArea(rectangle);
0223 }
0224 
0225 void DPreviewManager::setText(const QString& text, const QColor& color)
0226 {
0227     d->textLabel->setText(QString::fromLatin1("<qt text=\"%1\">%2</qt>").arg(color.name()).arg(text));
0228     setCurrentIndex(MessageMode);
0229 }
0230 
0231 void DPreviewManager::setBusy(bool b, const QString& text)
0232 {
0233     d->busy = b;
0234 
0235     if (d->busy)
0236     {
0237         setCursor(Qt::WaitCursor);
0238         d->progressTimer->start(300);
0239         setText(text);
0240     }
0241     else
0242     {
0243         unsetCursor();
0244         d->progressTimer->stop();
0245         setText(text);
0246         d->progressLabel->setPixmap(QPixmap());
0247     }
0248 }
0249 
0250 void DPreviewManager::slotProgressTimerDone()
0251 {
0252     d->progressLabel->setPixmap(d->progressPix->frameAt(d->progressCount));
0253     d->progressCount++;
0254 
0255     if (d->progressCount == 8)
0256     {
0257         d->progressCount = 0;
0258     }
0259 
0260     d->progressTimer->start(300);
0261 }
0262 
0263 } // namespace Digikam
0264 
0265 #include "moc_dpreviewmanager.cpp"