1 #include "common/common_pch.h"
2 
3 #include <QAction>
4 #include <QMenu>
5 #include <QMouseEvent>
6 #include <QTimer>
7 
8 #include "common/qt.h"
9 #include "mkvtoolnix-gui/forms/main_window/status_bar_progress_widget.h"
10 #include "mkvtoolnix-gui/jobs/tool.h"
11 #include "mkvtoolnix-gui/watch_jobs/tool.h"
12 #include "mkvtoolnix-gui/main_window/main_window.h"
13 #include "mkvtoolnix-gui/main_window/status_bar_progress_widget.h"
14 
15 namespace mtx::gui {
16 
17 class StatusBarProgressWidgetPrivate {
18   friend class StatusBarProgressWidget;
19 
20   std::unique_ptr<Ui::StatusBarProgressWidget> ui;
21   int m_numPendingAuto{}, m_numPendingManual{}, m_numRunning{}, m_numWarnings{}, m_numErrors{}, m_timerStep{};
22   QTimer m_timer;
23   QList<QPixmap> m_pixmaps;
24 
StatusBarProgressWidgetPrivate()25   explicit StatusBarProgressWidgetPrivate()
26     : ui{new Ui::StatusBarProgressWidget}
27   {
28   }
29 };
30 
StatusBarProgressWidget(QWidget * parent)31 StatusBarProgressWidget::StatusBarProgressWidget(QWidget *parent)
32   : QWidget{parent}
33   , p_ptr{new StatusBarProgressWidgetPrivate{}}
34 {
35   auto p = p_func();
36 
37   p->ui->setupUi(this);
38 
39   p->m_pixmaps << QPixmap{Q(":/icons/16x16/dialog-warning.png")};
40   p->m_pixmaps << QPixmap{Q(":/icons/16x16/dialog-warning-grayscale.png")};
41   p->m_pixmaps << QPixmap{Q(":/icons/16x16/dialog-error.png")};
42   p->m_pixmaps << QPixmap{Q(":/icons/16x16/dialog-error-grayscale.png")};
43 
44   p->m_timer.setInterval(1000);
45 
46   connect(&p->m_timer, &QTimer::timeout, this, &StatusBarProgressWidget::updateWarningsAndErrorsIcons);
47 }
48 
~StatusBarProgressWidget()49 StatusBarProgressWidget::~StatusBarProgressWidget() {
50 }
51 
52 void
reset()53 StatusBarProgressWidget::reset() {
54   setProgress(0, 0);
55 }
56 
57 void
setProgress(int progress,int totalProgress)58 StatusBarProgressWidget::setProgress(int progress,
59                                      int totalProgress) {
60   auto p = p_func();
61 
62   p->ui->progress->setValue(progress);
63   p->ui->totalProgress->setValue(totalProgress);
64 }
65 
66 void
setJobStats(int numPendingAuto,int numPendingManual,int numRunning,int)67 StatusBarProgressWidget::setJobStats(int numPendingAuto,
68                                      int numPendingManual,
69                                      int numRunning,
70                                      int) {
71   auto p                = p_func();
72   p->m_numPendingAuto   = numPendingAuto;
73   p->m_numPendingManual = numPendingManual;
74   p->m_numRunning       = numRunning;
75 
76   setLabelTexts();
77 }
78 
79 void
setNumUnacknowledgedWarningsOrErrors(int numWarnings,int numErrors)80 StatusBarProgressWidget::setNumUnacknowledgedWarningsOrErrors(int numWarnings,
81                                                               int numErrors) {
82   auto p           = p_func();
83   p->m_numWarnings = numWarnings;
84   p->m_numErrors   = numErrors;
85 
86   auto isActive = p->m_timer.isActive();
87 
88   if (!isActive && (p->m_numWarnings || p->m_numErrors)) {
89     p->m_timerStep = 0;
90     p->m_timer.start();
91 
92   } else if (isActive && !p->m_numWarnings && !p->m_numErrors) {
93     p->m_timer.stop();
94     updateWarningsAndErrorsIcons();
95   }
96 
97   setLabelTexts();
98 }
99 
100 void
retranslateUi()101 StatusBarProgressWidget::retranslateUi() {
102   p_func()->ui->retranslateUi(this);
103 
104   setLabelTexts();
105 }
106 
107 void
setLabelTexts()108 StatusBarProgressWidget::setLabelTexts() {
109   auto p = p_func();
110 
111   p->ui->numJobsLabel->setText(QY("%1 automatic, %2 manual, %3 running").arg(p->m_numPendingAuto).arg(p->m_numPendingManual).arg(p->m_numRunning));
112   p->ui->warningsLabel->setText(QNY("%1 warning", "%1 warnings", p->m_numWarnings).arg(p->m_numWarnings));
113   p->ui->errorsLabel  ->setText(QNY("%1 error",   "%1 errors",   p->m_numErrors)  .arg(p->m_numErrors));
114 }
115 
116 void
updateWarningsAndErrorsIcons()117 StatusBarProgressWidget::updateWarningsAndErrorsIcons() {
118   auto p             = p_func();
119   auto warningOffset = !p->m_numWarnings || !(p->m_timerStep % 2) ? 1 : 0;
120   auto errorOffset   = !p->m_numErrors   || !(p->m_timerStep % 2) ? 1 : 0;
121 
122   p->ui->warningsIconLabel->setPixmap(p->m_pixmaps[0 + warningOffset]);
123   p->ui->errorsIconLabel  ->setPixmap(p->m_pixmaps[2 + errorOffset]);
124 
125   ++p->m_timerStep;
126 }
127 
128 void
mouseReleaseEvent(QMouseEvent * event)129 StatusBarProgressWidget::mouseReleaseEvent(QMouseEvent *event) {
130   auto p = p_func();
131 
132   event->accept();
133 
134   QMenu menu{this};
135 
136   auto acknowledgeWarnings = new QAction{&menu};
137   auto acknowledgeErrors   = new QAction{&menu};
138   auto showJobQueue        = new QAction{&menu};
139   auto showJobOutput       = new QAction{&menu};
140 
141   acknowledgeWarnings->setText(QY("Acknowledge all &warnings"));
142   acknowledgeErrors->setText(QY("Acknowledge all &errors"));
143   showJobQueue->setText(QY("Show job queue && access job logs"));
144   showJobOutput->setText(QY("Show job output"));
145 
146   acknowledgeWarnings->setEnabled(!!p->m_numWarnings);
147   acknowledgeErrors->setEnabled(!!p->m_numErrors);
148 
149   connect(acknowledgeWarnings, &QAction::triggered, MainWindow::jobTool()->model(), &mtx::gui::Jobs::Model::acknowledgeAllWarnings);
150   connect(acknowledgeErrors,   &QAction::triggered, MainWindow::jobTool()->model(), &mtx::gui::Jobs::Model::acknowledgeAllErrors);
151   connect(showJobQueue,        &QAction::triggered, []{ MainWindow::get()->switchToTool(MainWindow::jobTool()); });
152   connect(showJobOutput,       &QAction::triggered, []{
153     auto tool = MainWindow::watchJobTool();
154     tool->switchToCurrentJobTab();
155     MainWindow::get()->switchToTool(tool);
156   });
157 
158   menu.addAction(acknowledgeWarnings);
159   menu.addAction(acknowledgeErrors);
160   menu.addSeparator();
161   menu.addAction(showJobQueue);
162   menu.addAction(showJobOutput);
163 
164   menu.exec(mapToGlobal(event->pos()));
165 }
166 
167 }
168