File indexing completed on 2024-04-21 04:52:28
0001 /* 0002 SPDX-FileCopyrightText: 2008 Marco Gittler <g.marco@freenet.de> 0003 SPDX-FileCopyrightText: Rafał Lalik 0004 0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 /* 0009 * * 0010 * Modifications by Rafał Lalik to implement Patterns mechanism * 0011 * * 0012 ***************************************************************************/ 0013 0014 #pragma once 0015 0016 #include "graphicsscenerectmove.h" 0017 #include "utils/timecode.h" 0018 #include "titler/titledocument.h" 0019 #include "titler/unicodedialog.h" 0020 #include "ui_titlewidget_ui.h" 0021 0022 #include <knewstuff_version.h> 0023 #include <KNSWidgets/Action> 0024 #include <QMap> 0025 #include <QModelIndex> 0026 #include <QSignalMapper> 0027 0028 class PatternsModel; 0029 0030 class Monitor; 0031 class KMessageWidget; 0032 class TimecodeDisplay; 0033 class TitleTemplate 0034 { 0035 public: 0036 QString file; 0037 QString name; 0038 QIcon icon; 0039 }; 0040 0041 class Transform 0042 { 0043 public: 0044 Transform() 0045 { 0046 scalex = 1.0; 0047 scaley = 1.0; 0048 rotatex = 0.0; 0049 rotatey = 0.0; 0050 rotatez = 0.0; 0051 } 0052 double scalex, scaley; 0053 int rotatex, rotatey, rotatez; 0054 }; 0055 0056 /** @class TitleWidget 0057 * @brief Title creation dialog 0058 * Instances of TitleWidget classes are instantiated by KdenliveDoc::slotCreateTextClip () 0059 */ 0060 class TitleWidget : public QDialog, public Ui::TitleWidget_UI 0061 { 0062 Q_OBJECT 0063 0064 public: 0065 /** @brief Draws the dialog and loads a title document (if any). 0066 * @param url title document to load 0067 * @param projectPath default path to save to or load from title documents 0068 * @param render project renderer 0069 * @param parent (optional) parent widget */ 0070 explicit TitleWidget(const QUrl &url, QString projectTitlePath, Monitor *monitor, QWidget *parent = nullptr); 0071 ~TitleWidget() override; 0072 QDomDocument xml(); 0073 void setXml(const QDomDocument &doc, const QString &id = QString()); 0074 0075 /** @brief Checks for the images referenced by a title clip. 0076 * @param xml XML data representing the title 0077 * @return list of the image files */ 0078 static QStringList extractImageList(QString &xml, const QString &root); 0079 /** @brief Checks for the images referenced by a title clip, and modifies the urls to ensure they are absolute 0080 * @param xml XML data representing the title 0081 * @return list of the image files / fonts */ 0082 static QPair<QStringList, QStringList> extractAndFixImageList(QDomElement &e, const QString &root); 0083 0084 /** @brief Checks for the fonts referenced by a title clip.\n 0085 * Called by DocumentChecker::hasErrorInClips () \n 0086 * @param xml XML data representing the title 0087 * @return list of the fonts in the title */ 0088 static QStringList extractFontList(const QString &xml); 0089 0090 /** @brief Returns clip duration. */ 0091 int duration() const; 0092 0093 /** @brief Retrieves a list of all available title templates. */ 0094 static void refreshTitleTemplates(const QString &projectPath); 0095 0096 /** @brief Returns a title name suggestion based on content */ 0097 const QString titleSuggest(); 0098 0099 protected: 0100 void resizeEvent(QResizeEvent *event) override; 0101 void keyPressEvent(QKeyEvent *e) override; 0102 0103 private: 0104 /** @brief Rectangle describing the animation start viewport. */ 0105 QGraphicsRectItem *m_startViewport; 0106 0107 /** @brief Rectangle describing the animation end viewport. */ 0108 QGraphicsRectItem *m_endViewport; 0109 0110 /** @brief Scene for the titler. */ 0111 GraphicsSceneRectMove *m_scene; 0112 0113 /** @brief Initialises the animation properties (viewport size, etc.). */ 0114 void initAnimation(); 0115 QMap<QGraphicsItem *, Transform> m_transformations; 0116 TitleDocument m_titledocument; 0117 QGraphicsRectItem *m_frameBorder; 0118 QGraphicsRectItem *m_frameBackground; 0119 QGraphicsPixmapItem *m_frameImage; 0120 QButtonGroup *m_textAlignGroup; 0121 int m_frameWidth; 0122 int m_frameHeight; 0123 int m_count; 0124 /** @brief Dialog for entering Unicode characters in text fields. */ 0125 UnicodeDialog *m_unicodeDialog; 0126 KMessageWidget *m_missingMessage; 0127 0128 /** @brief Project path for storing title documents. */ 0129 QString m_projectTitlePath; 0130 0131 /** @brief The project framerate. */ 0132 double m_fps; 0133 0134 /** @brief The bin id of the clip currently edited, can be empty if this is a new clip. */ 0135 QString m_clipId; 0136 0137 QAction *m_buttonRect; 0138 QAction *m_buttonEllipse; 0139 QAction *m_buttonText; 0140 QAction *m_buttonImage; 0141 QAction *m_buttonCursor; 0142 QAction *m_buttonSave; 0143 QAction *m_buttonLoad; 0144 KNSWidgets::Action *m_buttonDownload; 0145 0146 QAction *m_unicodeAction; 0147 QAction *m_zUp; 0148 QAction *m_zDown; 0149 QAction *m_zTop; 0150 QAction *m_zBottom; 0151 QAction *m_selectAll; 0152 QAction *m_selectText; 0153 QAction *m_selectRects; 0154 QAction *m_selectImages; 0155 QAction *m_unselectAll; 0156 QAction *m_createTitleAction; 0157 QString m_lastDocumentHash; 0158 QList<QGraphicsLineItem *> m_guides; 0159 0160 PatternsModel *m_patternsModel; 0161 0162 //QList<TitleTemplate> m_titleTemplates; 0163 0164 enum ValueType { ValueWidth = 1, ValueHeight = 2, ValueX = 4, ValueY = 8 }; 0165 0166 /** @brief Sets the font weight value in the combo box. (#909) */ 0167 void setFontBoxWeight(int weight); 0168 0169 /** @brief Stores the choices of font, background and rectangle values. */ 0170 void writeChoices(); 0171 0172 /** @brief Reads the last stored choices into the dialog. */ 0173 void readChoices(); 0174 0175 /** @brief Updates the displayed X/Y coordinates. */ 0176 void updateCoordinates(QGraphicsItem *i); 0177 0178 /** @brief Updates the displayed width/height/zindex values. */ 0179 void updateDimension(QGraphicsItem *i); 0180 0181 /** @brief Updates the displayed rotation/zoom values. Changes values of rotation/zoom GUI elements. */ 0182 void updateRotZoom(QGraphicsItem *i); 0183 0184 /** @brief Updates the item position (position read directly from the GUI). Does not change GUI elements. */ 0185 void updatePosition(QGraphicsItem *i); 0186 /** @brief Updates the item position. Does not change GUI elements. */ 0187 void updatePosition(QGraphicsItem *i, int x, int y); 0188 0189 void textChanged(MyTextItem *i); 0190 void updateAxisButtons(QGraphicsItem *i); 0191 0192 void updateTextOriginX(); 0193 void updateTextOriginY(); 0194 0195 /** @brief Enables the toolbars suiting to toolType. */ 0196 void enableToolbars(TITLETOOL toolType); 0197 0198 /** @brief Shows the toolbars suiting to toolType. */ 0199 void showToolbars(TITLETOOL toolType); 0200 0201 /** @brief Set up the tools suiting referenceItem */ 0202 void prepareTools(QGraphicsItem *referenceItem); 0203 0204 /** @brief Checks a tool button. */ 0205 void checkButton(TITLETOOL toolType); 0206 0207 void adjustFrameSize(); 0208 0209 /** @brief Adds a "start" and "end" info text to the animation viewports. */ 0210 void addAnimInfoText(); 0211 0212 /** @brief Updates the font for the "start" and "end" info text. */ 0213 void updateInfoText(); 0214 0215 /** @brief Removes the "start" and "end" info text from animation viewports. */ 0216 void deleteAnimInfoText(); 0217 0218 /** @brief Refreshes the contents of combobox based on list of title templates. */ 0219 void refreshTemplateBoxContents(); 0220 0221 qreal maxZIndex(); 0222 0223 /** @brief Gets the minimum/maximum Z index of items. 0224 * @param maxBound true: use maximum Z index; false: use minimum 0225 * @param intersectingOnly if true, consider only the items intersecting 0226 * with the currently selected item 0227 */ 0228 qreal zIndexBounds(bool maxBound, bool intersectingOnly); 0229 0230 void itemRotate(int val, int axis); 0231 0232 void selectItems(int itemType); 0233 0234 /** @brief Appends the shortcut of a QAction to a tooltip text */ 0235 QString getTooltipWithShortcut(const QString &tipText, QAction *button); 0236 void loadGradients(); 0237 void storeGradient(const QString &gradientData); 0238 0239 /** @brief Read patterns from config file 0240 */ 0241 void readPatterns(); 0242 /** @brief Write patterns to config file 0243 */ 0244 void writePatterns(); 0245 0246 public Q_SLOTS: 0247 void slotNewText(MyTextItem *tt); 0248 void slotNewRect(QGraphicsRectItem *rect); 0249 void slotNewEllipse(QGraphicsEllipseItem *rect); 0250 void slotChangeBackground(); 0251 0252 /** @brief Sets up the tools (toolbars etc.) according to the selected item. */ 0253 void selectionChanged(); 0254 void rectChanged(); 0255 void zIndexChanged(int); 0256 void itemScaled(int); 0257 void itemRotateX(int); 0258 void itemRotateY(int); 0259 void itemRotateZ(int); 0260 /** Save a title to a title file, returns the saved url or empty if error */ 0261 QUrl saveTitle(QUrl url = QUrl()); 0262 /** Load a title from a title file */ 0263 void loadTitle(QUrl url = QUrl()); 0264 void slotGotBackground(const QImage &img); 0265 0266 private Q_SLOTS: 0267 0268 /** @brief Switches the origin of the X axis between left and right border. 0269 * 0270 * It's called when the origin of the X coordinate has been changed. The X 0271 * origin will either be at the left or at the right side of the frame. 0272 * 0273 * When the origin of the X axis is at the left side, the user can enter the 0274 * distance between an element's left border and the left side of the frame. 0275 * 0276 * When on the right, the distance from the right border of the frame to the 0277 * right border of the element can be entered. This would result in negative 0278 * values as long as the element's right border is at the left of the 0279 * frame's right border. As that is usually the case, I additionally invert 0280 * the X axis. 0281 * 0282 * Default value is left. 0283 * 0284 * |----l----->|#######|----r--->| 0285 * | |---w-->| | 0286 * | |#######| | 0287 * | | 0288 * |----------m_frameWidth------>| 0289 * | | 0290 * 0291 * Left selected: Value = l 0292 * Right selected: Value = r 0293 * 0294 * To calculate between the two coordinate systems: 0295 * l = m_frameWidth - w - r 0296 * r = m_frameWidth - w - l 0297 */ 0298 void slotOriginXClicked(); 0299 0300 /** @brief Same as slotOriginXClicked(), but for the Y axis; default is top. 0301 * @ref slotOriginXClicked */ 0302 void slotOriginYClicked(); 0303 0304 /** @brief Updates coordinates of text fields if necessary. 0305 * 0306 * It's called when something changes in the QGraphicsScene. */ 0307 void slotChanged(); 0308 0309 /** 0310 * Reacts to changes of width/height/x/y QSpinBox values. 0311 * @brief Updates width, height, and position of the selected items. 0312 * @param valueType of type ValueType 0313 */ 0314 void slotValueChanged(int valueType); 0315 0316 void slotZoom(bool up); 0317 void slotUpdateZoom(int pos); 0318 void slotAdjustZoom(); 0319 void slotZoomOneToOne(); 0320 0321 void slotSelectAll(); 0322 void slotSelectText(); 0323 void slotSelectRects(); 0324 void slotSelectEllipses(); 0325 void slotSelectImages(); 0326 void slotSelectNone(); 0327 0328 /** Called whenever text properties change (font e.g.) */ 0329 void slotUpdateText(); 0330 void slotInsertUnicode(); 0331 void slotInsertUnicodeString(const QString &string); 0332 0333 void displayBackgroundFrame(); 0334 0335 void setCurrentItem(QGraphicsItem *item); 0336 0337 void slotTextTool(); 0338 void slotRectTool(); 0339 void slotEllipseTool(); 0340 void slotSelectTool(); 0341 void slotImageTool(); 0342 0343 void slotAnimStart(bool); 0344 void slotAnimEnd(bool); 0345 void slotKeepAspect(bool keep); 0346 0347 void itemHCenter(); 0348 void itemVCenter(); 0349 void itemTop(); 0350 void itemBottom(); 0351 void itemLeft(); 0352 void itemRight(); 0353 void slotResize(int percentSize); 0354 /** @brief Show hide guides */ 0355 void showGuides(int state); 0356 /** @brief Build guides */ 0357 void updateGuides(int); 0358 /** @brief guide color changed, repaint */ 0359 void guideColorChanged(const QColor &col); 0360 0361 /** @brief Called when accepted, stores user selections for next time use. 0362 * @ref writeChoices */ 0363 void slotAccepted(); 0364 0365 /** @brief Adds an effect to an element. 0366 * @param ix index of the effect in the effects menu 0367 * 0368 * The current implementation allows for one QGraphicsEffect to be added 0369 * along with the typewriter effect. This is not clear to the user: the 0370 * stack would help, and would permit us to make more QGraphicsEffects 0371 * coexist (with different layers of QGraphicsItems). */ 0372 void slotAddEffect(int ix); 0373 0374 /** @brief Changes the Z index of objects. */ 0375 void slotZIndexUp(); 0376 void slotZIndexDown(); 0377 void slotZIndexTop(); 0378 void slotZIndexBottom(); 0379 /** Called when the user wants to apply a different template to the title */ 0380 void templateIndexChanged(int); 0381 void slotEditGradient(); 0382 void slotUpdateShadow(); 0383 /** TW stuff */ 0384 void slotUpdateTW(); 0385 0386 /** @brief Remove missing items from the scene. */ 0387 void deleteMissingItems(); 0388 /** @brief List missing items from the scene. */ 0389 void showMissingItems(); 0390 0391 // slots for patterns list 0392 0393 /** @brief When scale slider is changed. */ 0394 void slotPatternsTileWidth(int width); 0395 /** @brief Pattern in the list double clicked. */ 0396 void slotPatternDblClicked(const QModelIndex & idx); 0397 /** @brief Pattern add button clicked. */ 0398 void slotPatternBtnAddClicked(); 0399 /** @brief Pattern remove button clicked. */ 0400 void slotPatternBtnRemoveClicked(); 0401 0402 Q_SIGNALS: 0403 void requestBackgroundFrame(bool request); 0404 void updatePatternsBackgroundFrame(); 0405 };