File indexing completed on 2024-04-28 08:43:45
0001 /* 0002 SPDX-FileCopyrightText: 2021 Jean-Baptiste Mardelle 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 #pragma once 0007 0008 #include "ui_textbasededit_ui.h" 0009 #include "definitions.h" 0010 #include "pythoninterfaces/speechtotext.h" 0011 0012 #include <QProcess> 0013 #include <QAction> 0014 #include <QTextEdit> 0015 #include <QMouseEvent> 0016 #include <QTimer> 0017 #include <QTemporaryFile> 0018 0019 class ProjectClip; 0020 0021 /** 0022 * @class VideoTextEdit: Video speech text editor 0023 * @brief A dialog for editing markers and guides. 0024 * @author Jean-Baptiste Mardelle 0025 */ 0026 class VideoTextEdit : public QTextEdit 0027 { 0028 Q_OBJECT 0029 0030 public: 0031 explicit VideoTextEdit(QWidget *parent = nullptr); 0032 void lineNumberAreaPaintEvent(QPaintEvent *event); 0033 int lineNumberAreaWidth(); 0034 void repaintLines(); 0035 void cleanup(); 0036 /** @brief returns the link for the first word at position start in the text. 0037 * This will seek forwards until a word is found in case selection starts with a space 0038 * @param cursor the current text cursor 0039 * @param start the first position of the selection 0040 * @param max the last position to check in seek operation*/ 0041 const QString selectionStartAnchor(QTextCursor &cursor, int start, int max); 0042 /** @brief returns the link for the last word at position end in the text. 0043 * This will seek backwards until a word is found in case selection ends with a space 0044 * @param cursor the current text cursor 0045 * @param end the last position of the selection 0046 * @param min the first position to check in seek operation*/ 0047 const QString selectionEndAnchor(QTextCursor &cursor, int end, int min); 0048 void checkHoverBlock(int yPos); 0049 void blockClicked(Qt::KeyboardModifiers modifiers, bool play = false); 0050 QVector<QPoint> processedZones(const QVector<QPoint> &sourceZones); 0051 QVector<QPoint> getInsertZones(); 0052 QVector<QPoint> fullExport(); 0053 /** @brief Remove all text outside loadZones 0054 */ 0055 void processCutZones(const QList <QPoint> &loadZones); 0056 void rebuildZones(); 0057 QVector< QPair<double, double> > speechZones; 0058 QVector <QPoint> cutZones; 0059 QAction *bookmarkAction; 0060 QAction *deleteAction; 0061 0062 protected: 0063 void mouseMoveEvent(QMouseEvent *e) override; 0064 void mousePressEvent(QMouseEvent *e) override; 0065 void mouseReleaseEvent(QMouseEvent *e) override; 0066 void keyPressEvent(QKeyEvent *e) override; 0067 void wheelEvent(QWheelEvent *e) override; 0068 void resizeEvent(QResizeEvent *e) override; 0069 void contextMenuEvent(QContextMenuEvent *event) override; 0070 0071 public Q_SLOTS: 0072 void slotRemoveSilence(); 0073 0074 private Q_SLOTS: 0075 void updateLineNumberArea(const QRect &rect, int dy); 0076 0077 private: 0078 QWidget *lineNumberArea; 0079 int m_hoveredBlock{-1}; 0080 int m_lastClickedBlock{-1}; 0081 QVector <int> m_selectedBlocks; 0082 int getFirstVisibleBlockId(); 0083 }; 0084 0085 class LineNumberArea : public QWidget 0086 { 0087 public: 0088 LineNumberArea(VideoTextEdit *editor) : QWidget(editor), codeEditor(editor) 0089 { 0090 setMouseTracking(true); 0091 } 0092 0093 QSize sizeHint() const override 0094 { 0095 return QSize(codeEditor->lineNumberAreaWidth(), 0); 0096 } 0097 0098 protected: 0099 void paintEvent(QPaintEvent *event) override 0100 { 0101 codeEditor->lineNumberAreaPaintEvent(event); 0102 } 0103 void mouseMoveEvent(QMouseEvent *e) override 0104 { 0105 codeEditor->checkHoverBlock(e->pos().y()); 0106 QWidget::mouseMoveEvent(e); 0107 } 0108 void mousePressEvent(QMouseEvent *e) override 0109 { 0110 codeEditor->blockClicked(e->modifiers()); 0111 QWidget::mousePressEvent(e); 0112 } 0113 void mouseDoubleClickEvent(QMouseEvent *e) override 0114 { 0115 codeEditor->blockClicked(e->modifiers(), true); 0116 QWidget::mouseDoubleClickEvent(e); 0117 } 0118 void wheelEvent(QWheelEvent *e) override 0119 { 0120 qDebug()<<"==== WHEEL OVER LINEAREA"; 0121 e->ignore(); 0122 //QWidget::wheelEvent(e); 0123 } 0124 void leaveEvent(QEvent *e) override 0125 { 0126 codeEditor->checkHoverBlock(-1); 0127 QWidget::leaveEvent(e); 0128 } 0129 0130 private: 0131 VideoTextEdit *codeEditor; 0132 }; 0133 0134 /** 0135 * @class TextBasedEdit: Subtitle edit widget 0136 * @brief A dialog for editing markers and guides. 0137 * @author Jean-Baptiste Mardelle 0138 */ 0139 class TextBasedEdit : public QWidget, public Ui::TextBasedEdit_UI 0140 { 0141 Q_OBJECT 0142 0143 public: 0144 explicit TextBasedEdit(QWidget *parent = nullptr); 0145 ~TextBasedEdit() override; 0146 void openClip(std::shared_ptr<ProjectClip>); 0147 0148 public Q_SLOTS: 0149 void deleteItem(); 0150 0151 private Q_SLOTS: 0152 void startRecognition(); 0153 void slotProcessSpeech(); 0154 void slotProcessWhisperSpeech(); 0155 void slotProcessSpeechError(); 0156 void slotProcessSpeechStatus(int, QProcess::ExitStatus status); 0157 /** @brief insert currently selected zones to timeline */ 0158 void insertToTimeline(); 0159 /** @brief Preview current edited text in the clip monitor */ 0160 void previewPlaylist(bool createNew = true); 0161 /** @brief Create a timeline sequence with current edit */ 0162 void createSequence(); 0163 /** @brief Display info message */ 0164 void showMessage(const QString &text, KMessageWidget::MessageType type, QAction *action = nullptr); 0165 void addBookmark(); 0166 void updateEngine(); 0167 void slotZoomIn(); 0168 void slotZoomOut(); 0169 0170 protected: 0171 bool eventFilter(QObject *obj, QEvent *event) override; 0172 0173 private: 0174 std::unique_ptr<QProcess> m_speechJob; 0175 std::unique_ptr<QProcess> m_tCodeJob; 0176 /** @brief Id of the master bin clip on which speech processing is done */ 0177 QString m_binId; 0178 /** @brief Id of the playlist which is processed from the master clip */ 0179 QString m_refId; 0180 QString m_sourceUrl; 0181 double m_clipDuration{0.}; 0182 int m_lastPosition; 0183 QString m_errorString; 0184 QAction *m_logAction; 0185 QAction *m_voskConfig; 0186 QAction *m_currentMessageAction{nullptr}; 0187 VideoTextEdit *m_visualEditor; 0188 QTextDocument m_document; 0189 QString m_playlist; 0190 QTimer m_hideTimer; 0191 double m_clipOffset; 0192 QTemporaryFile m_playlistWav; 0193 QTemporaryFile m_tmpCutWav; 0194 QAction *m_translateAction; 0195 SpeechToText *m_stt; 0196 void applyFontSize(); 0197 };