12#include "ui_recorderdocker.h"
18#include <klocalizedstring.h>
36#include <QRegularExpression>
40const QString keyActionRecordToggle =
"recorder_record_toggle";
41const QString keyActionExport =
"recorder_export";
43const QString activeColorGreen(
" color='#5cab25'");
44const QString inactiveColorGreen(
" color='#b4e196'");
45const QString activeColorOrange(
" color='#ca8f14'");
46const QString inactiveColorOrange(
" color='#ffe5af'");
47const QString activeColorRed(
" color='#da4453'");
48const QString inactiveColorRed(
" color='#f2c4c9'");
49const QString inactiveColorGray(
" color='#3e3e3e'");
51const QColor textColorOrange(0xff, 0xe5, 0xaf);
52const QColor buttonColorOrange(0xca, 0x8f, 0x14);
53const QColor textColorRed(0xf2, 0xc4, 0xc9);
54const QColor buttonColorRed(0xda, 0x44, 0x53);
63 QScopedPointer<Ui::RecorderDocker>
ui;
94 ,
ui(new
Ui::RecorderDocker())
147 title = i18nc(
"Title for label. JPEG Quality level",
"Quality:");
148 hint = i18nc(
"@tooltip",
"Greater value will produce a larger file and a better quality. Doesn't affect CPU consumption.\nValues lower than 50 are not recommended due to high artifacts.");
156 title = i18nc(
"Title for label. PNG Compression level",
"Compression:");
157 hint = i18nc(
"@tooltip",
"Greater value will produce a smaller file but will require more from your CPU. Doesn't affect quality.\nCompression set to 0 is not recommended due to high disk space consumption.\nValues above 3 are not recommended due to high performance impact.");
165 ui->comboFormat->setCurrentIndex(index);
166 ui->labelQuality->setText(title);
167 ui->spinQuality->setToolTip(hint);
168 QSignalBlocker blocker(
ui->spinQuality);
169 ui->spinQuality->setMinimum(minValue);
170 ui->spinQuality->setMaximum(maxValue);
171 ui->spinQuality->setValue(factor);
172 ui->spinQuality->setSuffix(suffix);
182 QSignalBlocker blocker(
ui->spinRate);
185 title = i18nc(
"Title for label. Video frames per second",
"Video FPS:");
194 title = i18nc(
"Title for label. Capture rate",
"Capture interval:");
204 ui->labelRate->setText(title);
205 ui->spinRate->setDecimals(decimals);
206 ui->spinRate->setMinimum(minValue);
207 ui->spinRate->setMaximum(maxValue);
208 ui->spinRate->setSuffix(suffix);
229 :
canvas->imageView()->document()->documentInfo()->aboutInfo(
"creation-date").remove(QRegularExpression(
"[^0-9]"));
235 i18nc(
"Use original resolution for the frames when recording the canvas",
"Original"),
236 i18nc(
"Use the resolution two times smaller than the original resolution for the frames when recording the canvas",
"Half"),
237 i18nc(
"Use the resolution four times smaller than the original resolution for the frames when recording the canvas",
"Quarter")
241 for (
int index = 0, len = titles.length(); index < len; ++index) {
242 int divider = 1 << index;
243 items += QString(
"%1 (%2x%3)").arg(titles[index])
244 .arg((width / divider) & ~1)
245 .arg((height / divider) & ~1);
247 QSignalBlocker blocker(
ui->comboResolution);
248 const int currentIndex =
ui->comboResolution->currentIndex();
249 ui->comboResolution->clear();
250 ui->comboResolution->addItems(items);
251 ui->comboResolution->setCurrentIndex(currentIndex);
259 QSignalBlocker blocker(
ui->buttonRecordToggle);
260 ui->buttonRecordToggle->setChecked(isRecording);
262 ui->buttonRecordToggle->setText(isRecording ? i18nc(
"Stop recording the canvas",
"Stop")
263 : i18nc(
"Start recording the canvas",
"Record"));
264 ui->buttonRecordToggle->setEnabled(
true);
266 ui->widgetSettings->setEnabled(!isRecording);
288 QString label(
"<font style='letter-spacing:-4px'>");
290 QString inactiveColor;
293 if (threadNr > threads) {
294 activeColor = inactiveColorGray;
295 inactiveColor = inactiveColorGray;
297 activeColor = activeColorRed;
298 inactiveColor = inactiveColorRed;
300 activeColor = activeColorOrange;
301 inactiveColor = inactiveColorOrange;
303 activeColor = activeColorGreen;
304 inactiveColor = inactiveColorGreen;
306 label.append(QString(
"<font%1>▍</font>")
307 .arg(threadNr <= threadsInUse ? activeColor : inactiveColor));
310 label.append(QString(
"</font><font> %1 </font><font%2>●</font>")
311 .arg(i18nc(
"Recording symbol",
"REC"))
312 .arg(
paused ?
"" : activeColorRed));
314 statusBarLabel->setToolTip(
paused ? i18n(
"Recorder is paused") : QString(i18n(
"Active recording with %1 of %2 available threads")).arg(threadsInUse).arg(threads));
333 pal.setColor(QPalette::Text, textColorRed);
334 pal.setColor(QPalette::Button, buttonColorRed);
335 ui->spinThreads->setPalette(pal);
336 ui->sliderThreads->setPalette(pal);
337 toolTipText = QString(
338 i18n(
"Set the number of recording threads.\nThe number of threads exceeds the ideal max number of your hardware setup.\nPlease be aware, that a number greater than %1 probably won't give you any performance boost.")
344 pal.setColor(QPalette::Text, textColorOrange);
345 pal.setColor(QPalette::Button, buttonColorOrange);
346 ui->spinThreads->setPalette(pal);
347 ui->sliderThreads->setPalette(pal);
348 toolTipText = QString(
349 i18n(
"Set the number of recording threads.\nAccording to your hardware setup you should record with no more than %1 threads.\nYou can play around with one or two more threads, but keep an eye on your overall system performance.")
354 toolTipText = i18n(
"Set the number of threads to be used for recording.");
356 ui->spinThreads->setToolTip(toolTipText);
357 ui->sliderThreads->setToolTip(toolTipText);
362 : QDockWidget(i18nc(
"Title of the docker",
"Recorder"))
364 , d(new
Private(*exportSettings, this))
366 QWidget* page =
new QWidget(
this);
367 d->
ui->setupUi(page);
373 d->
ui->sliderThreads->setTickPosition(QSlider::TickPosition::TicksBelow);
374 d->
ui->sliderThreads->setMinimum(1);
376 d->
ui->spinThreads->setMinimum(1);
399 connect(
d->
ui->buttonRecordToggle, SIGNAL(toggled(
bool)),
d->
ui->buttonExport, SLOT(setDisabled(
bool)));
401 d->
ui->buttonExport->setDisabled(
true);
431 connect(scroller, SIGNAL(stateChanged(QScroller::State)),
438 d->
ui->checkBoxRealTimeCaptureMode->setCheckState(Qt::Unchecked);
439 d->
ui->checkBoxRealTimeCaptureMode->setDisabled(
true);
440 d->
ui->checkBoxRealTimeCaptureMode->setToolTip(
441 i18n(
"Your system is not efficient enough for this feature"));
455 setEnabled(canvas !=
nullptr);
470 bool wasToggled =
false;
480 bool enabled =
d->
enabledIds.value(document->linkedResourcesStorageId(),
false);
505 QSignalBlocker blocker(
d->
ui->buttonRecordToggle);
511 const QString &
id =
d->
canvas->imageView()->document()->linkedResourcesStorageId();
513 bool wasEmpty = !
d->
enabledIds.values().contains(
true);
517 bool isEmpty = !
d->
enabledIds.values().contains(
true);
521 if (isEmpty == wasEmpty) {
527 d->
ui->buttonRecordToggle->setEnabled(
false);
567 exportDialog.
setup();
584 dialog.setCaption(i18n(
"Select a Directory for Recordings"));
585 dialog.setDefaultDir(
d->
ui->editDirectory->text());
586 QString directory = dialog.filename();
587 if (!directory.isEmpty()) {
588 d->
ui->editDirectory->setText(directory);
690 if (!valueWasIncreased)
705 QMessageBox::warning(
this, i18nc(
"@title:window",
"Recorder"),
706 i18n(
"The recorder has been stopped due to failure while writing a frame. Please check free disk space and start the recorder again."));
711 QMessageBox::warning(
this, i18nc(
"@title:window",
"Recorder"),
712 i18n(
"Krita was unable to stop the recorder probably. Please try to restart Krita."));
717 d->
showWarning(i18n(
"Low performance warning. The recorder is not able to write all the frames in time during Real Time Capture mode.\nTry to reduce the frame rate for the ffmpeg export or reduce the scaling filtering in the canvas acceleration settings."));
719 d->
showWarning(i18n(
"Low performance warning. The recorder is not able to write all the frames in time.\nTry to increase the capture interval or reduce the scaling filtering in the canvas acceleration settings."));
float value(const T *src, size_t ch)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
QAction * makeQAction(const QString &name, QObject *parent=0)
static KisActionRegistry * instance()
A container for a set of QAction objects.
Q_INVOKABLE QAction * addAction(const QString &name, QAction *action)
KisViewManager * viewManager
static KisPart * instance()
void removeExtraWidget(QWidget *widget)
void addExtraWidget(QWidget *widget)
virtual KisKActionCollection * actionCollection() const
double captureInterval() const
QString snapshotDirectory() const
void setFormat(RecorderFormat value)
void setRealTimeCaptureMode(bool value)
bool recordIsolateLayerMode() const
RecorderFormat format() const
void setRecordAutomatically(bool value)
void setResolution(int value)
void setCaptureInterval(double value)
void setSnapshotDirectory(const QString &value)
void setRecordIsolateLayerMode(bool value)
void setCompression(int value)
bool recordAutomatically() const
void setQuality(int value)
bool realTimeCaptureMode() const
void setThreads(int value)
bool recordIsolateLayerMode
QPointer< KisCanvas2 > canvas
void showWarning(const QString &hint)
QString snapshotDirectory
void loadRelevantExportSettings()
QPalette threadsSpinPalette
RecorderWriterManager writer
QMap< QString, bool > enabledIds
Private(const RecorderExportSettings &es, RecorderDockerDock *q_ptr)
void updateUiForRealTimeMode()
QScopedPointer< Ui::RecorderDocker > ui
void updateWriterSettings()
void updateRecIndicator()
void updateRecordStatus(bool isRecording)
QAction * recordToggleAction
QLabel * statusBarWarningLabel
RecorderDockerDock *const q
void updateComboResolution(quint32 width, quint32 height)
QPalette threadsSliderPalette
void slotScrollerStateChanged(QScroller::State state)
RecorderExportSettings *const exportSettings
void onManageRecordingsButtonClicked()
void onCaptureIntervalChanged(double interval)
void setCanvas(KoCanvasBase *canvas) override
void onThreadsChanged(int threads)
void onVideoFPSChanged(double interval)
void onQualityChanged(int value)
void onWriterFrameWriteFailed()
void onRecordIsolateLayerModeToggled(bool checked)
void onUpdateRecIndicator()
void onRealTimeCaptureModeToggled(bool checked)
void unsetCanvas() override
void onResolutionChanged(int resolution)
bool onRecordButtonToggled(bool checked)
void onAutoRecordToggled(bool checked)
void onRecorderStopWarning()
void onActiveRecording(bool valueWasIncreased)
void onMainWindowIsBeingCreated(KisMainWindow *window)
void onLowPerformanceWarning()
void onSelectRecordFolderButtonClicked()
void onExportButtonClicked()
void onFormatChanged(int format)
void execFor(const QString &snapshotsDirectory)
void start(bool toggleEnabled=true)
void setCanvas(QPointer< KisCanvas2 > canvas)
bool stop(bool toggleEnabled=true)
void setEnabled(bool enabled)
void setup(const RecorderWriterSettings &settings)
ThreadCounter recorderThreads
unsigned int getUsed() const
QIcon loadIcon(const QString &name)
const unsigned int IdealRecordThreadCount
const unsigned int MaxThreadCount
const unsigned int MaxRecordThreadCount
bool realTimeCaptureModeWasSet