File indexing completed on 2024-04-21 04:51:23
0001 /* 0002 SPDX-FileCopyrightText: 2008 Jean-Baptiste Mardelle <jb@kdenlive.org> 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 #pragma once 0007 0008 #include <QPainter> 0009 #include <QPushButton> 0010 #include <QStyledItemDelegate> 0011 0012 namespace Purpose { 0013 class Menu; 0014 } 0015 0016 #include "bin/model/markerlistmodel.hpp" 0017 #include "definitions.h" 0018 #include "render/renderrequest.h" 0019 #include "renderpresets/renderpresetmodel.hpp" 0020 #include "renderpresets/tree/renderpresettreemodel.hpp" 0021 #include "ui_renderwidget_ui.h" 0022 #include <KNSWidgets/Button> 0023 #include <knewstuff_version.h> 0024 0025 class QDomElement; 0026 class QKeyEvent; 0027 0028 // RenderViewDelegate is used to draw the progress bars. 0029 class RenderViewDelegate : public QStyledItemDelegate 0030 { 0031 Q_OBJECT 0032 public: 0033 explicit RenderViewDelegate(QWidget *parent) 0034 : QStyledItemDelegate(parent) 0035 { 0036 } 0037 0038 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override 0039 { 0040 if (index.column() == 1) { 0041 painter->save(); 0042 QStyleOptionViewItem opt(option); 0043 QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); 0044 const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; 0045 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); 0046 0047 QFont font = painter->font(); 0048 font.setBold(true); 0049 painter->setFont(font); 0050 QRect r1 = option.rect; 0051 r1.adjust(0, textMargin, 0, -textMargin); 0052 int mid = int((r1.height() / 2)); 0053 r1.setBottom(r1.y() + mid); 0054 QRect bounding; 0055 painter->drawText(r1, Qt::AlignLeft | Qt::AlignTop, index.data().toString(), &bounding); 0056 r1.moveTop(r1.bottom() - textMargin); 0057 font.setBold(false); 0058 painter->setFont(font); 0059 painter->drawText(r1, Qt::AlignLeft | Qt::AlignTop, index.data(Qt::UserRole).toString()); 0060 int progress = index.data(Qt::UserRole + 3).toInt(); 0061 if (progress > 0 && progress < 100) { 0062 // draw progress bar 0063 QColor color = option.palette.alternateBase().color(); 0064 QColor fgColor = option.palette.text().color(); 0065 color.setAlpha(150); 0066 fgColor.setAlpha(150); 0067 painter->setBrush(QBrush(color)); 0068 painter->setPen(QPen(fgColor)); 0069 int width = qMin(200, r1.width() - 4); 0070 QRect bgrect(r1.left() + 2, option.rect.bottom() - 6 - textMargin, width, 6); 0071 painter->drawRoundedRect(bgrect, 3, 3); 0072 painter->setBrush(QBrush(fgColor)); 0073 bgrect.adjust(2, 2, 0, -1); 0074 painter->setPen(Qt::NoPen); 0075 bgrect.setWidth((width - 2) * progress / 100); 0076 painter->drawRect(bgrect); 0077 } else { 0078 r1.setBottom(opt.rect.bottom()); 0079 r1.setTop(r1.bottom() - mid); 0080 painter->drawText(r1, Qt::AlignLeft | Qt::AlignBottom, index.data(Qt::UserRole + 5).toString()); 0081 } 0082 painter->restore(); 0083 } else { 0084 QStyledItemDelegate::paint(painter, option, index); 0085 } 0086 } 0087 }; 0088 0089 class RenderJobItem : public QTreeWidgetItem 0090 { 0091 public: 0092 explicit RenderJobItem(QTreeWidget *parent, const QStringList &strings, int type = QTreeWidgetItem::Type); 0093 void setStatus(int status); 0094 int status() const; 0095 void setMetadata(const QString &data); 0096 const QString metadata() const; 0097 0098 private: 0099 int m_status; 0100 QString m_data; 0101 }; 0102 0103 class RenderWidget : public QDialog 0104 { 0105 Q_OBJECT 0106 0107 public: 0108 enum RenderError { 0109 CompositeError = 0, 0110 PresetError = 1, 0111 ProxyWarning = 2, 0112 PlaybackError = 3, 0113 OptionsError = 4 0114 }; 0115 0116 explicit RenderWidget(bool enableProxy, QWidget *parent = nullptr); 0117 ~RenderWidget() override; 0118 void saveConfig(); 0119 void loadConfig(); 0120 void setGuides(std::weak_ptr<MarkerListModel> guidesModel); 0121 void focusItem(const QString &profile = QString()); 0122 void setRenderProgress(const QString &dest, int progress = 0, int frame = 0); 0123 void setRenderStatus(const QString &dest, int status, const QString &error); 0124 void setRenderProfile(const QMap<QString, QString> &props); 0125 void saveRenderProfile(); 0126 void updateDocumentPath(); 0127 int waitingJobsCount() const; 0128 int runningJobsCount() const; 0129 QString getFreeScriptName(const QUrl &projectName = QUrl(), const QString &prefix = QString()); 0130 bool startWaitingRenderJobs(); 0131 /** @brief Show / hide proxy settings. */ 0132 void updateProxyConfig(bool enable); 0133 0134 /** @brief Display warning message in render widget. */ 0135 void errorMessage(RenderError type, const QString &message); 0136 /** @brief Update the render duration info when project duration changes. */ 0137 void projectDurationChanged(int duration); 0138 /** @brief Update the render duration info when zone changes. */ 0139 void zoneDurationChanged(int duration); 0140 /** @brief Update the render duration info. */ 0141 void showRenderDuration(); 0142 0143 protected: 0144 QSize sizeHint() const override; 0145 void keyPressEvent(QKeyEvent *e) override; 0146 void parseProfile(QDomElement profile, QTreeWidgetItem *childitem, QString groupName, 0147 QString extension = QString(), QString renderer = QStringLiteral("avformat")); 0148 0149 public Q_SLOTS: 0150 void slotAbortCurrentJob(); 0151 void slotPrepareExport(bool scriptExport = false); 0152 void adjustViewToProfile(); 0153 void reloadGuides(); 0154 /** @brief Adjust render file name to current project name. */ 0155 void resetRenderPath(const QString &path); 0156 /** @brief Update metadata tooltip with current values. */ 0157 void updateMetadataToolTip(); 0158 /** @brief Update missing clip info. */ 0159 void updateMissingClipsCount(int total, int used); 0160 0161 private Q_SLOTS: 0162 /** 0163 * Will be called when the user selects an output file via the file dialog. 0164 * File extension will be added automatically. 0165 */ 0166 void slotUpdateButtons(const QUrl &url); 0167 /** 0168 * Will be called when the user changes the output file path in the text line. 0169 * File extension must NOT be added, would make editing impossible! 0170 */ 0171 void slotUpdateButtons(); 0172 void refreshView(); 0173 0174 void slotChangeSelection(const QModelIndex ¤t, const QModelIndex &previous); 0175 /** @brief Updates available options when a new format has been selected. */ 0176 void loadProfile(); 0177 void refreshParams(); 0178 void slotSavePresetAs(); 0179 void slotNewPreset(); 0180 void slotEditPreset(); 0181 0182 void slotRenderModeChanged(); 0183 void slotUpdateRescaleHeight(int); 0184 void slotUpdateRescaleWidth(int); 0185 void slotCheckStartGuidePosition(); 0186 void slotCheckEndGuidePosition(); 0187 /** @brief Enable / disable the rescale options. */ 0188 void setRescaleEnabled(bool enable); 0189 /** @brief Show updated command parameter in tooltip. */ 0190 void adjustSpeed(int videoQuality); 0191 0192 void slotStartScript(); 0193 void slotDeleteScript(); 0194 void parseScriptFiles(); 0195 void slotCheckScript(); 0196 void slotCheckJob(); 0197 void slotCleanUpJobs(); 0198 0199 void slotHideLog(); 0200 void slotPlayRendering(QTreeWidgetItem *item, int); 0201 void slotStartCurrentJob(); 0202 /** @brief User shared a rendered file, give feedback. */ 0203 void slotShareActionFinished(const QJsonObject &output, int error, const QString &message); 0204 /** @brief running jobs menu. */ 0205 void prepareJobContextMenu(const QPoint &pos); 0206 /** @brief Prepare the render request. */ 0207 void slotPrepareExport2(bool scriptExport = false); 0208 0209 private: 0210 enum Tabs { 0211 RenderTab = 0, 0212 JobsTab, 0213 ScriptsTab 0214 }; 0215 0216 Ui::RenderWidget_UI m_view; 0217 QString m_projectFolder; 0218 RenderViewDelegate *m_scriptsDelegate; 0219 RenderViewDelegate *m_jobsDelegate; 0220 bool m_blockProcessing; 0221 QMap<int, QString> m_errorMessages; 0222 std::weak_ptr<MarkerListModel> m_guidesModel; 0223 std::shared_ptr<RenderPresetTreeModel> m_treeModel; 0224 QString m_currentProfile; 0225 RenderPresetParams m_params; 0226 int m_renderDuration{0}; 0227 int m_missingClips{0}; 0228 int m_missingUsedClips{0}; 0229 0230 Purpose::Menu *m_shareMenu; 0231 void parseProfiles(const QString &selectedProfile = QString()); 0232 QUrl filenameWithExtension(QUrl url, const QString &extension); 0233 /** @brief Check if a job needs to be started. */ 0234 void checkRenderStatus(); 0235 void startRendering(RenderJobItem *item); 0236 /** @brief Create a rendering profile from MLT preset. */ 0237 QTreeWidgetItem *loadFromMltPreset(const QString &groupName, const QString &path, QString profileName, bool codecInName = false); 0238 RenderJobItem *createRenderJob(const RenderRequest::RenderJob &job); 0239 void updateRenderInfoMessage(); 0240 0241 Q_SIGNALS: 0242 void abortProcess(const QString &url); 0243 /** Send the info about rendering that will be saved in the document: 0244 (profile destination, profile name and url of rendered file) */ 0245 void selectedRenderProfile(const QMap<QString, QString> &renderProps); 0246 void shutdown(); 0247 };