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 }