File indexing completed on 2024-11-10 04:26:06

0001 /*
0002 SPDX-FileCopyrightText: 2016 Jean-Baptiste Mardelle <jb@kdenlive.org>
0003 This file is part of Kdenlive. See www.kdenlive.org.
0004 
0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #include "progressbutton.h"
0009 
0010 #include <KLocalizedString>
0011 #include <QAction>
0012 #include <QPainter>
0013 
0014 ProgressButton::ProgressButton(const QString &text, double max, QWidget *parent)
0015     : QToolButton(parent)
0016     , m_defaultAction(nullptr)
0017     , m_max(max)
0018 {
0019     setPopupMode(MenuButtonPopup);
0020     m_progress = width() - 6;
0021     m_iconSize = height() - 4;
0022     m_progressFont = font();
0023     m_progressFont.setPixelSize(m_iconSize / 2);
0024     initStyleOption(&m_buttonStyle);
0025     QPixmap pix(m_iconSize, m_iconSize);
0026     pix.fill(Qt::transparent);
0027     m_dummyAction = new QAction(QIcon(pix), text, this);
0028 }
0029 
0030 ProgressButton::~ProgressButton()
0031 {
0032     delete m_dummyAction;
0033 }
0034 
0035 void ProgressButton::defineDefaultAction(QAction *action, QAction *actionInProgress)
0036 {
0037     setDefaultAction(action);
0038     m_defaultAction = action;
0039     if (actionInProgress) {
0040         connect(m_dummyAction, &QAction::triggered, actionInProgress, &QAction::trigger);
0041     }
0042 }
0043 
0044 void ProgressButton::setProgress(int progress)
0045 {
0046     int prog = m_iconSize * progress / m_max;
0047     QString remaining;
0048     if (m_timer.isValid() && progress > 0) {
0049         // calculate remaining time
0050         qint64 ms = m_timer.elapsed() * (m_max - progress) / progress;
0051         if (ms < 60000)
0052         // xgettext:no-c-format
0053         {
0054             remaining = i18nc("s as seconds", "%1s", ms / 1000);
0055         } else if (ms < 3600000)
0056         // xgettext:no-c-format
0057         {
0058             remaining = i18nc("m as minutes", "%1m", ms / 60000);
0059         } else {
0060             remaining = i18nc("h as hours", "%1h", qMin(99, (int)(ms / 3600000)));
0061         }
0062     }
0063     if (progress < 0) {
0064         setDefaultAction(m_defaultAction);
0065         m_remainingTime.clear();
0066         m_timer.invalidate();
0067         m_progress = -1;
0068         update();
0069         return;
0070     }
0071     if (!m_timer.isValid() || progress == 0) {
0072         setDefaultAction(m_dummyAction);
0073         m_timer.start();
0074     }
0075     if (progress == m_max) {
0076         setDefaultAction(m_defaultAction);
0077         m_remainingTime.clear();
0078         m_timer.invalidate();
0079     }
0080     if (remaining != m_remainingTime || m_progress != prog) {
0081         m_progress = prog;
0082         m_remainingTime = remaining;
0083         update();
0084     } else {
0085         m_progress = prog;
0086         m_remainingTime = remaining;
0087     }
0088 }
0089 
0090 int ProgressButton::progress() const
0091 {
0092     return m_progress;
0093 }
0094 
0095 void ProgressButton::paintEvent(QPaintEvent *event)
0096 {
0097     QToolButton::paintEvent(event);
0098     if (m_progress < m_iconSize) {
0099         QPainter painter(this);
0100         painter.setFont(m_progressFont);
0101         painter.setRenderHint(QPainter::Antialiasing, true);
0102         QRect rect(3, (height() - m_iconSize) / 2, m_iconSize, m_iconSize);
0103         // draw remaining time
0104         if (m_remainingTime.isEmpty() && m_progress >= 0) {
0105             // We just started task, no time estimation yet, display starting status
0106             if (m_defaultAction) {
0107                 painter.drawPixmap(rect.adjusted(4, 0, -4, -8), m_defaultAction->icon().pixmap(m_iconSize - 8, m_iconSize - 8));
0108             }
0109         } else {
0110             painter.drawText(rect, Qt::AlignHCenter, m_remainingTime);
0111         }
0112         if (m_progress < 0) {
0113             painter.fillRect(rect.x(), rect.bottom() - 5, rect.width(), 3, Qt::red);
0114         } else {
0115             QColor w(Qt::white);
0116             w.setAlpha(40);
0117             painter.fillRect(rect.x(), rect.bottom() - 6, m_progress, 4, palette().highlight().color());
0118             painter.fillRect(rect.x(), rect.bottom() - 6, rect.width(), 4, w);
0119         }
0120         painter.setPen(palette().shadow().color());
0121         painter.drawRoundedRect(rect.x(), rect.bottom() - 7, rect.width(), 6, 2, 2);
0122     }
0123 }