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 };