titlewidget.cpp 110 KB
Newer Older
1
/***************************************************************************
2
                          titlewidget.cpp  -  description
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
                             -------------------
    begin                : Feb 28 2008
    copyright            : (C) 2008 by Marco Gittler
    email                : g.marco@freenet.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

18
#include "titlewidget.h"
19
#include "gradientwidget.h"
20
#include "kdenlivesettings.h"
Vincent Pinon's avatar
Vincent Pinon committed
21
#include "doc/kthumb.h"
22
#include "renderer.h"
23
#include "KoSliderCombo.h"
24
#include "utils/KoIconUtils.h"
Vincent Pinon's avatar
Vincent Pinon committed
25

Simon Eugster's avatar
Simon Eugster committed
26 27
#include <cmath>

28
#include <KMessageBox>
29
#include <klocalizedstring.h>
30
#include <KRecentDirs>
31

Laurent Montel's avatar
Laurent Montel committed
32
#include "kdenlive_debug.h"
33 34
#include <QFontDatabase>
#include <QFileDialog>
35
#include <QDomDocument>
Marco Gittler's avatar
Marco Gittler committed
36
#include <QGraphicsItem>
37
#include <QGraphicsSvgItem>
38
#include <QTimer>
39
#include <QToolBar>
40
#include <QSignalMapper>
41 42
#include <QTextBlockFormat>
#include <QTextCursor>
43
#include <QCryptographicHash>
44
#include <QKeyEvent>
45
#include <QImageReader>
46

47 48 49 50
#include <QGraphicsEffect>
#include <QGraphicsBlurEffect>
#include <QGraphicsDropShadowEffect>

51
#include <iostream>
52
#include <QStandardPaths>
53

54 55
static QList<TitleTemplate> titletemplates;

56
// What exactly is this variable good for?
57 58
int settingUp = false;

59 60 61 62
const int IMAGEITEM = 7;
const int RECTITEM = 3;
const int TEXTITEM = 8;

63 64 65 66 67
const int NOEFFECT = 0;
const int BLUREFFECT = 1;
const int SHADOWEFFECT = 2;
const int TYPEWRITEREFFECT = 3;

68
TitleWidget::TitleWidget(const QUrl &url, const Timecode &tc, const QString &projectTitlePath, Render *render, QWidget *parent) :
Laurent Montel's avatar
Laurent Montel committed
69 70
    QDialog(parent),
    Ui::TitleWidget_UI(),
Laurent Montel's avatar
Laurent Montel committed
71 72
    m_startViewport(nullptr),
    m_endViewport(nullptr),
Laurent Montel's avatar
Laurent Montel committed
73 74 75
    m_count(0),
    m_unicodeDialog(new UnicodeDialog(UnicodeDialog::InputHex)),
    m_projectTitlePath(projectTitlePath),
76 77
    m_tc(tc),
    m_fps(render->fps())
78
{
79
    setupUi(this);
80
    setMinimumSize(200, 200);
81
    setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
82
    frame_properties->setEnabled(false);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
83
    frame_properties->setFixedHeight(frame_toolbar->height());
84 85
    int size = style()->pixelMetric(QStyle::PM_SmallIconSize);
    QSize iconSize(size, size);
86

87 88 89 90
    rectBColor->setAlphaChannelEnabled(true);
    rectFColor->setAlphaChannelEnabled(true);
    fontColorButton->setAlphaChannelEnabled(true);
    textOutlineColor->setAlphaChannelEnabled(true);
91
    shadowColor->setAlphaChannelEnabled(true);
92

93 94 95 96 97 98 99 100 101
    QButtonGroup *colorGroup = new QButtonGroup(this);
    colorGroup->addButton(gradient_color);
    colorGroup->addButton(plain_color);

    QButtonGroup *alignGroup = new QButtonGroup(this);
    alignGroup->addButton(buttonAlignLeft);
    alignGroup->addButton(buttonAlignCenter);
    alignGroup->addButton(buttonAlignRight);

102 103
    textOutline->setMinimum(0);
    textOutline->setMaximum(200);
104
    //textOutline->setDecimals(0);
105 106
    textOutline->setValue(0);
    textOutline->setToolTip(i18n("Outline width"));
107 108 109

    backgroundAlpha->setMinimum(0);
    backgroundAlpha->setMaximum(255);
110 111
    bgAlphaSlider->setMinimum(0);
    bgAlphaSlider->setMaximum(255);
112 113 114
    backgroundAlpha->setValue(0);
    backgroundAlpha->setToolTip(i18n("Background color opacity"));

115 116
    itemrotatex->setMinimum(-360);
    itemrotatex->setMaximum(360);
117
    //itemrotatex->setDecimals(0);
118 119 120 121 122
    itemrotatex->setValue(0);
    itemrotatex->setToolTip(i18n("Rotation around the X axis"));

    itemrotatey->setMinimum(-360);
    itemrotatey->setMaximum(360);
123
    //itemrotatey->setDecimals(0);
124 125 126 127 128
    itemrotatey->setValue(0);
    itemrotatey->setToolTip(i18n("Rotation around the Y axis"));

    itemrotatez->setMinimum(-360);
    itemrotatez->setMaximum(360);
129
    //itemrotatez->setDecimals(0);
130 131
    itemrotatez->setValue(0);
    itemrotatez->setToolTip(i18n("Rotation around the Z axis"));
132 133

    rectLineWidth->setMinimum(0);
134
    rectLineWidth->setMaximum(500);
135
    //rectLineWidth->setDecimals(0);
136 137 138
    rectLineWidth->setValue(0);
    rectLineWidth->setToolTip(i18n("Border width"));

139
    itemzoom->setSuffix(i18n("%"));
140 141
    m_frameWidth = render->renderWidth();
    m_frameHeight = render->renderHeight();
142
    showToolbars(TITLE_SELECT);
143

144 145
    splitter->setStretchFactor(0, 20);

146
    //If project is drop frame, set the input mask as such.
147
    title_duration->setInputMask(m_tc.mask());
148
    title_duration->setText(m_tc.reformatSeparators(KdenliveSettings::title_duration()));
149

Laurent Montel's avatar
Laurent Montel committed
150 151
    connect(backgroundColor, &KColorButton::changed, this, &TitleWidget::slotChangeBackground);
    connect(backgroundAlpha, SIGNAL(valueChanged(int)), this, SLOT(slotChangeBackground()));
152

Laurent Montel's avatar
Laurent Montel committed
153 154
    connect(shadowBox, &QGroupBox::toggled, this, &TitleWidget::slotUpdateShadow);
    connect(shadowColor, &KColorButton::changed, this, &TitleWidget::slotUpdateShadow);
155 156 157 158
    connect(blur_radius, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateShadow()));
    connect(shadowX, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateShadow()));
    connect(shadowY, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateShadow()));

Laurent Montel's avatar
Laurent Montel committed
159 160 161
    connect(fontColorButton, &KColorButton::changed, this, &TitleWidget::slotUpdateText);
    connect(plain_color, &QAbstractButton::clicked, this, &TitleWidget::slotUpdateText);
    connect(gradient_color, &QAbstractButton::clicked, this, &TitleWidget::slotUpdateText);
162 163
    connect(gradients_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateText()));

Laurent Montel's avatar
Laurent Montel committed
164 165
    connect(textOutlineColor, &KColorButton::changed, this, &TitleWidget::slotUpdateText);
    connect(font_family, &QFontComboBox::currentFontChanged, this, &TitleWidget::slotUpdateText);
166
    connect(font_size, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText()));
Laurent Montel's avatar
Laurent Montel committed
167 168
    connect(letter_spacing, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText()));
    connect(line_spacing, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText()));
169
    connect(textOutline, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText()));
Simon Eugster's avatar
Titler:  
Simon Eugster committed
170
    connect(font_weight_box, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateText()));
171

Laurent Montel's avatar
Laurent Montel committed
172 173 174 175
    connect(rectFColor, &KColorButton::changed, this, &TitleWidget::rectChanged);
    connect(rectBColor, &KColorButton::changed, this, &TitleWidget::rectChanged);
    connect(plain_rect, &QAbstractButton::clicked, this, &TitleWidget::rectChanged);
    connect(gradient_rect, &QAbstractButton::clicked, this, &TitleWidget::rectChanged);
176
    connect(gradients_rect_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(rectChanged()));
177
    connect(rectLineWidth, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
178

179 180
    // Fill effects, NOT SUPPORTED in titler version 2
    /*effect_list->addItem(i18n("None"), NOEFFECT);
181
    if (render->getMltVersionInfo(QStringLiteral("kdenlivetitle")) > 1.0) {
Laurent Montel's avatar
Laurent Montel committed
182 183
    // there was a bug in MLT's kdenlivetitle module version 1 that crashed on typewriter effect
    effect_list->addItem(i18n("Typewriter"), TYPEWRITEREFFECT);
184
    }
185
    effect_list->addItem(i18n("Blur"), BLUREFFECT);*/
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
186

187 188
    connect(zValue, SIGNAL(valueChanged(int)), this, SLOT(zIndexChanged(int)));
    connect(itemzoom, SIGNAL(valueChanged(int)), this, SLOT(itemScaled(int)));
189 190 191
    connect(itemrotatex, SIGNAL(valueChanged(int)), this, SLOT(itemRotateX(int)));
    connect(itemrotatey, SIGNAL(valueChanged(int)), this, SLOT(itemRotateY(int)));
    connect(itemrotatez, SIGNAL(valueChanged(int)), this, SLOT(itemRotateZ(int)));
Laurent Montel's avatar
Laurent Montel committed
192 193 194 195 196 197
    connect(itemhcenter, &QAbstractButton::clicked, this, &TitleWidget::itemHCenter);
    connect(itemvcenter, &QAbstractButton::clicked, this, &TitleWidget::itemVCenter);
    connect(itemtop, &QAbstractButton::clicked, this, &TitleWidget::itemTop);
    connect(itembottom, &QAbstractButton::clicked, this, &TitleWidget::itemBottom);
    connect(itemleft, &QAbstractButton::clicked, this, &TitleWidget::itemLeft);
    connect(itemright, &QAbstractButton::clicked, this, &TitleWidget::itemRight);
198
    connect(effect_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotAddEffect(int)));
199
    connect(typewriter_delay, SIGNAL(valueChanged(int)), this, SLOT(slotEditTypewriter(int)));
200
    connect(typewriter_start, SIGNAL(valueChanged(int)), this, SLOT(slotEditTypewriter(int)));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
201

Laurent Montel's avatar
Laurent Montel committed
202 203
    connect(origin_x_left, &QAbstractButton::clicked, this, &TitleWidget::slotOriginXClicked);
    connect(origin_y_top, &QAbstractButton::clicked, this, &TitleWidget::slotOriginYClicked);
204

Laurent Montel's avatar
Laurent Montel committed
205
    connect(render, &AbstractRender::frameUpdated, this, &TitleWidget::slotGotBackground);
Simon Eugster's avatar
Simon Eugster committed
206

207
    // Position and size
208 209 210
    m_signalMapper = new QSignalMapper(this);
    m_signalMapper->setMapping(value_w, ValueWidth);
    m_signalMapper->setMapping(value_h, ValueHeight);
211 212
    m_signalMapper->setMapping(value_x, ValueX);
    m_signalMapper->setMapping(value_y, ValueY);
213 214
    connect(value_w, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
    connect(value_h, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
215 216
    connect(value_x, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
    connect(value_y, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
217 218
    connect(m_signalMapper, SIGNAL(mapped(int)), this, SLOT(slotValueChanged(int)));

Laurent Montel's avatar
Laurent Montel committed
219 220 221 222 223 224 225 226 227 228
    connect(buttonFitZoom, &QAbstractButton::clicked, this, &TitleWidget::slotAdjustZoom);
    connect(buttonRealSize, &QAbstractButton::clicked, this, &TitleWidget::slotZoomOneToOne);
    connect(buttonItalic, &QAbstractButton::clicked, this, &TitleWidget::slotUpdateText);
    connect(buttonUnder, &QAbstractButton::clicked, this, &TitleWidget::slotUpdateText);
    connect(buttonAlignLeft, &QAbstractButton::clicked, this, &TitleWidget::slotUpdateText);
    connect(buttonAlignRight, &QAbstractButton::clicked, this, &TitleWidget::slotUpdateText);
    connect(buttonAlignCenter, &QAbstractButton::clicked, this, &TitleWidget::slotUpdateText);
    connect(edit_gradient, &QAbstractButton::clicked, this, &TitleWidget::slotEditGradient);
    connect(edit_rect_gradient, &QAbstractButton::clicked, this, &TitleWidget::slotEditGradient);
    connect(displayBg, &QCheckBox::stateChanged, this, &TitleWidget::displayBackgroundFrame);
229

Laurent Montel's avatar
Laurent Montel committed
230
    connect(m_unicodeDialog, &UnicodeDialog::charSelected, this, &TitleWidget::slotInsertUnicodeString);
Simon Eugster's avatar
Simon Eugster committed
231

232
    // mbd
Laurent Montel's avatar
Laurent Montel committed
233
    connect(this, &QDialog::accepted, this, &TitleWidget::slotAccepted);
Mads Bondo Dydensborg's avatar
Mads Bondo Dydensborg committed
234

Simon Eugster's avatar
Titler:  
Simon Eugster committed
235 236 237 238 239 240 241 242 243 244
    font_weight_box->blockSignals(true);
    font_weight_box->addItem(i18nc("Font style", "Light"), QFont::Light);
    font_weight_box->addItem(i18nc("Font style", "Normal"), QFont::Normal);
    font_weight_box->addItem(i18nc("Font style", "Demi-Bold"), QFont::DemiBold);
    font_weight_box->addItem(i18nc("Font style", "Bold"), QFont::Bold);
    font_weight_box->addItem(i18nc("Font style", "Black"), QFont::Black);
    font_weight_box->setToolTip(i18n("Font weight"));
    font_weight_box->setCurrentIndex(1);
    font_weight_box->blockSignals(false);

245 246 247 248 249 250 251
    buttonFitZoom->setIconSize(iconSize);
    buttonRealSize->setIconSize(iconSize);
    buttonItalic->setIconSize(iconSize);
    buttonUnder->setIconSize(iconSize);
    buttonAlignCenter->setIconSize(iconSize);
    buttonAlignLeft->setIconSize(iconSize);
    buttonAlignRight->setIconSize(iconSize);
252 253 254 255 256 257 258
    buttonFitZoom->setIcon(KoIconUtils::themedIcon(QStringLiteral("zoom-fit-best")));
    buttonRealSize->setIcon(KoIconUtils::themedIcon(QStringLiteral("zoom-original")));
    buttonItalic->setIcon(KoIconUtils::themedIcon(QStringLiteral("format-text-italic")));
    buttonUnder->setIcon(KoIconUtils::themedIcon(QStringLiteral("format-text-underline")));
    buttonAlignCenter->setIcon(KoIconUtils::themedIcon(QStringLiteral("format-justify-center")));
    buttonAlignLeft->setIcon(KoIconUtils::themedIcon(QStringLiteral("format-justify-left")));
    buttonAlignRight->setIcon(KoIconUtils::themedIcon(QStringLiteral("format-justify-right")));
259 260
    edit_gradient->setIcon(KoIconUtils::themedIcon(QStringLiteral("document-edit")));
    edit_rect_gradient->setIcon(KoIconUtils::themedIcon(QStringLiteral("document-edit")));
261

262 263 264
    buttonAlignRight->setToolTip(i18n("Align right"));
    buttonAlignLeft->setToolTip(i18n("Align left"));
    buttonAlignCenter->setToolTip(i18n("Align center"));
265
    buttonAlignLeft->setChecked(true);
266

267
    m_unicodeAction = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-insert-unicode")), QString(), this);
268
    m_unicodeAction->setShortcut(Qt::SHIFT + Qt::CTRL + Qt::Key_U);
269
    m_unicodeAction->setToolTip(getTooltipWithShortcut(i18n("Insert Unicode character"), m_unicodeAction));
Laurent Montel's avatar
Laurent Montel committed
270
    connect(m_unicodeAction, &QAction::triggered, this, &TitleWidget::slotInsertUnicode);
271
    buttonInsertUnicode->setDefaultAction(m_unicodeAction);
272

273
    m_zUp = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-zindex-up")), QString(), this);
Simon Eugster's avatar
Simon Eugster committed
274 275
    m_zUp->setShortcut(Qt::Key_PageUp);
    m_zUp->setToolTip(i18n("Raise object"));
Laurent Montel's avatar
Laurent Montel committed
276
    connect(m_zUp, &QAction::triggered, this, &TitleWidget::slotZIndexUp);
Simon Eugster's avatar
Simon Eugster committed
277
    zUp->setDefaultAction(m_zUp);
278

279
    m_zDown = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-zindex-down")), QString(), this);
Simon Eugster's avatar
Simon Eugster committed
280 281
    m_zDown->setShortcut(Qt::Key_PageDown);
    m_zDown->setToolTip(i18n("Lower object"));
Laurent Montel's avatar
Laurent Montel committed
282
    connect(m_zDown, &QAction::triggered, this, &TitleWidget::slotZIndexDown);
Simon Eugster's avatar
Simon Eugster committed
283
    zDown->setDefaultAction(m_zDown);
284

285
    m_zTop = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-zindex-top")), QString(), this);
Alberto Villa's avatar
Alberto Villa committed
286
    // TODO mbt 1414: Shortcut should change z index only if
287 288
    // cursor is NOT in a text field ...
    //m_zTop->setShortcut(Qt::Key_Home);
Simon Eugster's avatar
Simon Eugster committed
289
    m_zTop->setToolTip(i18n("Raise object to top"));
Laurent Montel's avatar
Laurent Montel committed
290
    connect(m_zTop, &QAction::triggered, this, &TitleWidget::slotZIndexTop);
Simon Eugster's avatar
Simon Eugster committed
291
    zTop->setDefaultAction(m_zTop);
292

293
    m_zBottom = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-zindex-bottom")), QString(), this);
294 295
    // TODO mbt 1414
    //m_zBottom->setShortcut(Qt::Key_End);
Simon Eugster's avatar
Simon Eugster committed
296
    m_zBottom->setToolTip(i18n("Lower object to bottom"));
Laurent Montel's avatar
Laurent Montel committed
297
    connect(m_zBottom, &QAction::triggered, this, &TitleWidget::slotZIndexBottom);
Simon Eugster's avatar
Simon Eugster committed
298
    zBottom->setDefaultAction(m_zBottom);
299

300
    m_selectAll = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-select-all")), QString(), this);
301
    m_selectAll->setShortcut(Qt::CTRL + Qt::Key_A);
Laurent Montel's avatar
Laurent Montel committed
302
    connect(m_selectAll, &QAction::triggered, this, &TitleWidget::slotSelectAll);
303
    buttonSelectAll->setDefaultAction(m_selectAll);
304

305
    m_selectText = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-select-texts")), QString(), this);
306
    m_selectText->setShortcut(Qt::CTRL + Qt::Key_T);
Laurent Montel's avatar
Laurent Montel committed
307
    connect(m_selectText, &QAction::triggered, this, &TitleWidget::slotSelectText);
308
    buttonSelectText->setDefaultAction(m_selectText);
309 310
    buttonSelectText->setEnabled(false);

311
    m_selectRects = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-select-rects")), QString(), this);
312
    m_selectRects->setShortcut(Qt::CTRL + Qt::Key_R);
Laurent Montel's avatar
Laurent Montel committed
313
    connect(m_selectRects, &QAction::triggered, this, &TitleWidget::slotSelectRects);
314
    buttonSelectRects->setDefaultAction(m_selectRects);
315 316
    buttonSelectRects->setEnabled(false);

317
    m_selectImages = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-select-images")), QString(), this);
318
    m_selectImages->setShortcut(Qt::CTRL + Qt::Key_I);
Laurent Montel's avatar
Laurent Montel committed
319
    connect(m_selectImages, &QAction::triggered, this, &TitleWidget::slotSelectImages);
320
    buttonSelectImages->setDefaultAction(m_selectImages);
321 322
    buttonSelectImages->setEnabled(false);

323
    m_unselectAll = new QAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-unselect-all")), QString(), this);
324
    m_unselectAll->setShortcut(Qt::SHIFT + Qt::CTRL + Qt::Key_A);
Laurent Montel's avatar
Laurent Montel committed
325
    connect(m_unselectAll, &QAction::triggered, this, &TitleWidget::slotSelectNone);
326
    buttonUnselectAll->setDefaultAction(m_unselectAll);
327
    buttonUnselectAll->setEnabled(false);
328

329 330 331
    zDown->setIconSize(iconSize);
    zTop->setIconSize(iconSize);
    zBottom->setIconSize(iconSize);
332 333 334
    zDown->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-zindex-down")));
    zTop->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-zindex-top")));
    zBottom->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-zindex-bottom")));
Laurent Montel's avatar
Laurent Montel committed
335 336 337
    connect(zDown, &QAbstractButton::clicked, this, &TitleWidget::slotZIndexDown);
    connect(zTop, &QAbstractButton::clicked, this, &TitleWidget::slotZIndexTop);
    connect(zBottom, &QAbstractButton::clicked, this, &TitleWidget::slotZIndexBottom);
338

Alberto Villa's avatar
Alberto Villa committed
339 340 341 342 343 344 345
    origin_x_left->setToolTip(i18n("Invert x axis and change 0 point"));
    origin_y_top->setToolTip(i18n("Invert y axis and change 0 point"));
    rectBColor->setToolTip(i18n("Select fill color"));
    rectFColor->setToolTip(i18n("Select border color"));
    zoom_slider->setToolTip(i18n("Zoom"));
    buttonRealSize->setToolTip(i18n("Original size (1:1)"));
    buttonFitZoom->setToolTip(i18n("Fit zoom"));
346
    backgroundColor->setToolTip(i18n("Select background color"));
Simon Eugster's avatar
Simon Eugster committed
347
    backgroundAlpha->setToolTip(i18n("Background opacity"));
348 349 350 351 352
    buttonSelectAll->setToolTip(getTooltipWithShortcut(i18n("Select all"), m_selectAll));
    buttonSelectText->setToolTip(getTooltipWithShortcut(i18n("Select text items in current selection"), m_selectText));
    buttonSelectRects->setToolTip(getTooltipWithShortcut(i18n("Select rect items in current selection"), m_selectRects));
    buttonSelectImages->setToolTip(getTooltipWithShortcut(i18n("Select image items in current selection"), m_selectImages));
    buttonUnselectAll->setToolTip(getTooltipWithShortcut(i18n("Unselect all"), m_unselectAll));
353

354 355 356 357 358 359
    itemhcenter->setIconSize(iconSize);
    itemvcenter->setIconSize(iconSize);
    itemtop->setIconSize(iconSize);
    itembottom->setIconSize(iconSize);
    itemright->setIconSize(iconSize);
    itemleft->setIconSize(iconSize);
360

361
    itemhcenter->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-align-hor")));
362
    itemhcenter->setToolTip(i18n("Align item horizontally"));
363
    itemvcenter->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-align-vert")));
364
    itemvcenter->setToolTip(i18n("Align item vertically"));
365
    itemtop->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-align-top")));
366
    itemtop->setToolTip(i18n("Align item to top"));
367
    itembottom->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-align-bottom")));
368
    itembottom->setToolTip(i18n("Align item to bottom"));
369
    itemright->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-align-right")));
370
    itemright->setToolTip(i18n("Align item to right"));
371
    itemleft->setIcon(KoIconUtils::themedIcon(QStringLiteral("kdenlive-align-left")));
372
    itemleft->setToolTip(i18n("Align item to left"));
373

374 375
    QHBoxLayout *layout = new QHBoxLayout;
    frame_toolbar->setLayout(layout);
376
    layout->setContentsMargins(0, 0, 0, 0);
377
    QToolBar *m_toolbar = new QToolBar(QStringLiteral("titleToolBar"), this);
378
    m_toolbar->setIconSize(iconSize);
379

380
    m_buttonCursor = m_toolbar->addAction(KoIconUtils::themedIcon(QStringLiteral("transform-move")), i18n("Selection Tool"));
381 382
    m_buttonCursor->setCheckable(true);
    m_buttonCursor->setShortcut(Qt::ALT + Qt::Key_S);
Laurent Montel's avatar
Laurent Montel committed
383
    m_buttonCursor->setToolTip(i18n("Selection Tool") + QLatin1Char(' ') + m_buttonCursor->shortcut().toString());
Laurent Montel's avatar
Laurent Montel committed
384
    connect(m_buttonCursor, &QAction::triggered, this, &TitleWidget::slotSelectTool);
385

386
    m_buttonText = m_toolbar->addAction(KoIconUtils::themedIcon(QStringLiteral("insert-text")), i18n("Add Text"));
387
    m_buttonText->setCheckable(true);
Alberto Villa's avatar
Alberto Villa committed
388
    m_buttonText->setShortcut(Qt::ALT + Qt::Key_T);
Laurent Montel's avatar
Laurent Montel committed
389
    m_buttonText->setToolTip(i18n("Add Text") + QLatin1Char(' ') + m_buttonText->shortcut().toString());
Laurent Montel's avatar
Laurent Montel committed
390
    connect(m_buttonText, &QAction::triggered, this, &TitleWidget::slotTextTool);
391

392
    m_buttonRect = m_toolbar->addAction(KoIconUtils::themedIcon(QStringLiteral("kdenlive-insert-rect")), i18n("Add Rectangle"));
393 394
    m_buttonRect->setCheckable(true);
    m_buttonRect->setShortcut(Qt::ALT + Qt::Key_R);
Laurent Montel's avatar
Laurent Montel committed
395
    m_buttonRect->setToolTip(i18n("Add Rectangle") + QLatin1Char(' ') + m_buttonRect->shortcut().toString());
Laurent Montel's avatar
Laurent Montel committed
396
    connect(m_buttonRect, &QAction::triggered, this, &TitleWidget::slotRectTool);
397

398
    m_buttonImage = m_toolbar->addAction(KoIconUtils::themedIcon(QStringLiteral("insert-image")), i18n("Add Image"));
399
    m_buttonImage->setCheckable(false);
Alberto Villa's avatar
Alberto Villa committed
400
    m_buttonImage->setShortcut(Qt::ALT + Qt::Key_I);
Laurent Montel's avatar
Laurent Montel committed
401
    m_buttonImage->setToolTip(i18n("Add Image") + QLatin1Char(' ') + m_buttonImage->shortcut().toString());
Laurent Montel's avatar
Laurent Montel committed
402
    connect(m_buttonImage, &QAction::triggered, this, &TitleWidget::slotImageTool);
403

Simon Eugster's avatar
Simon Eugster committed
404
    m_toolbar->addSeparator();
405

406
    m_buttonLoad = m_toolbar->addAction(KoIconUtils::themedIcon(QStringLiteral("document-open")), i18n("Open Document"));
407
    m_buttonLoad->setCheckable(false);
Alberto Villa's avatar
Alberto Villa committed
408
    m_buttonLoad->setShortcut(Qt::CTRL + Qt::Key_O);
Laurent Montel's avatar
Laurent Montel committed
409
    m_buttonLoad->setToolTip(i18n("Open Document") + QLatin1Char(' ') + m_buttonLoad->shortcut().toString());
410 411
    connect(m_buttonLoad, SIGNAL(triggered()), this, SLOT(loadTitle()));

412
    m_buttonSave = m_toolbar->addAction(KoIconUtils::themedIcon(QStringLiteral("document-save-as")), i18n("Save As"));
413
    m_buttonSave->setCheckable(false);
Alberto Villa's avatar
Alberto Villa committed
414
    m_buttonSave->setShortcut(Qt::CTRL + Qt::Key_S);
Laurent Montel's avatar
Laurent Montel committed
415
    m_buttonSave->setToolTip(i18n("Save As") + QLatin1Char(' ') + m_buttonSave->shortcut().toString());
416 417 418
    connect(m_buttonSave, SIGNAL(triggered()), this, SLOT(saveTitle()));

    layout->addWidget(m_toolbar);
419

420
    // initialize graphic scene
421
    m_scene = new GraphicsSceneRectMove(this);
422
    graphicsView->setScene(m_scene);
423
    graphicsView->setMouseTracking(true);
424
    graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
425 426
    graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
    graphicsView->setRubberBandSelectionMode(Qt::ContainsItemBoundingRect);
427
    m_titledocument.setScene(m_scene, m_frameWidth, m_frameHeight);
Laurent Montel's avatar
Laurent Montel committed
428
    connect(m_scene, &QGraphicsScene::changed, this, &TitleWidget::slotChanged);
429
    connect(font_size, SIGNAL(valueChanged(int)), m_scene, SLOT(slotUpdateFontSize(int)));
Laurent Montel's avatar
Laurent Montel committed
430
    connect(use_grid, &QAbstractButton::toggled, m_scene, &GraphicsSceneRectMove::slotUseGrid);
431

432 433
    // Video frame rect
    QPen framepen;
434 435 436
    framepen.setColor(Qt::red);
    m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
    m_frameBorder->setPen(framepen);
437
    m_frameBorder->setZValue(1000);
438
    m_frameBorder->setBrush(Qt::transparent);
Laurent Montel's avatar
Laurent Montel committed
439
    m_frameBorder->setFlags(nullptr);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
440
    m_frameBorder->setData(-1, -1);
441
    graphicsView->scene()->addItem(m_frameBorder);
442

443
    // semi transparent safe zones
444
    framepen.setColor(QColor(255, 0, 0, 100));
445 446 447
    QGraphicsRectItem *safe1 = new QGraphicsRectItem(QRectF(m_frameWidth * 0.05, m_frameHeight * 0.05, m_frameWidth * 0.9, m_frameHeight * 0.9), m_frameBorder);
    safe1->setBrush(Qt::transparent);
    safe1->setPen(framepen);
Laurent Montel's avatar
Laurent Montel committed
448
    safe1->setFlags(nullptr);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
449
    safe1->setData(-1, -1);
450 451 452
    QGraphicsRectItem *safe2 = new QGraphicsRectItem(QRectF(m_frameWidth * 0.1, m_frameHeight * 0.1, m_frameWidth * 0.8, m_frameHeight * 0.8), m_frameBorder);
    safe2->setBrush(Qt::transparent);
    safe2->setPen(framepen);
Laurent Montel's avatar
Laurent Montel committed
453
    safe2->setFlags(nullptr);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
454
    safe2->setData(-1, -1);
455 456 457 458

    m_frameBackground = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
    m_frameBackground->setZValue(-1100);
    m_frameBackground->setBrush(Qt::transparent);
Laurent Montel's avatar
Laurent Montel committed
459
    m_frameBackground->setFlags(nullptr);
460 461
    graphicsView->scene()->addItem(m_frameBackground);

462 463 464 465 466
    m_frameImage = new QGraphicsPixmapItem();
    QTransform qtrans;
    qtrans.scale(2.0, 2.0);
    m_frameImage->setTransform(qtrans);
    m_frameImage->setZValue(-1200);
Laurent Montel's avatar
Laurent Montel committed
467
    m_frameImage->setFlags(nullptr);
468 469 470
    displayBackgroundFrame();
    graphicsView->scene()->addItem(m_frameImage);

Laurent Montel's avatar
Laurent Montel committed
471 472 473 474 475 476 477
    connect(m_scene, &QGraphicsScene::selectionChanged, this, &TitleWidget::selectionChanged);
    connect(m_scene, &GraphicsSceneRectMove::itemMoved, this, &TitleWidget::selectionChanged);
    connect(m_scene, &GraphicsSceneRectMove::sceneZoom, this, &TitleWidget::slotZoom);
    connect(m_scene, &GraphicsSceneRectMove::actionFinished, this, &TitleWidget::slotSelectTool);
    connect(m_scene, &GraphicsSceneRectMove::newRect, this, &TitleWidget::slotNewRect);
    connect(m_scene, &GraphicsSceneRectMove::newText, this, &TitleWidget::slotNewText);
    connect(zoom_slider, &QAbstractSlider::valueChanged, this, &TitleWidget::slotUpdateZoom);
478
    connect(zoom_spin, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateZoom(int)));
479

480
    // mbd: load saved settings
481
    loadGradients();
482
    readChoices();
Mads Bondo Dydensborg's avatar
Mads Bondo Dydensborg committed
483

484 485 486 487 488 489 490 491 492 493 494
    if (render->getMltVersionInfo(QStringLiteral("kdenlivetitle")) < 2.0) {
        // Gradients and shadows are only supported since version 2, so disable
        shadowBox->setEnabled(false);
        gradient_color->setEnabled(false);
        gradients_combo->setEnabled(false);
        gradients_rect_combo->setEnabled(false);
        gradient_rect->setEnabled(false);
        edit_gradient->setEnabled(false);
        edit_rect_gradient->setEnabled(false);
    }

495 496 497
    // Hide effects not implemented
    tabWidget->removeTab(3);

498 499
    graphicsView->show();
    graphicsView->setInteractive(true);
Laurent Montel's avatar
Laurent Montel committed
500
    //qCDebug(KDENLIVE_LOG) << "// TITLE WIDGWT: " << graphicsView->viewport()->width() << 'x' << graphicsView->viewport()->height();
501
    m_startViewport = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
502 503
    // Setting data at -1 so that the item is recognized as undeletable by graphicsscenerectmove
    m_startViewport->setData(-1, -1);
504
    m_endViewport = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
505
    m_endViewport->setData(-1, -1);
506 507 508 509
    m_startViewport->setData(0, m_frameWidth);
    m_startViewport->setData(1, m_frameHeight);
    m_endViewport->setData(0, m_frameWidth);
    m_endViewport->setData(1, m_frameHeight);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
510

511 512
    // scale the view so that the title widget is not too big at startup
    graphicsView->scale(.5, .5);
513
    if (url.isValid()) {
Laurent Montel's avatar
Laurent Montel committed
514 515
        loadTitle(url);
    } else {
Laurent Montel's avatar
Laurent Montel committed
516
        prepareTools(nullptr);
Laurent Montel's avatar
Laurent Montel committed
517
        slotTextTool();
Laurent Montel's avatar
Laurent Montel committed
518
        QTimer::singleShot(200, this, &TitleWidget::slotAdjustZoom);
519
    }
520
    initAnimation();
521 522 523 524
    QColor color = backgroundColor->color();
    m_scene->setBackgroundBrush(QBrush(color));
    color.setAlpha(backgroundAlpha->value());
    m_frameBackground->setBrush(color);
Laurent Montel's avatar
Laurent Montel committed
525 526
    connect(anim_start, &QAbstractButton::toggled, this, &TitleWidget::slotAnimStart);
    connect(anim_end, &QAbstractButton::toggled, this, &TitleWidget::slotAnimEnd);
527
    connect(templateBox, SIGNAL(currentIndexChanged(int)), this, SLOT(templateIndexChanged(int)));
528 529

    buttonBox->button(QDialogButtonBox::Ok)->setEnabled(KdenliveSettings::hastitleproducer());
530 531 532
    if (titletemplates.isEmpty()) {
        refreshTitleTemplates(m_projectTitlePath);
    }
533 534
    //templateBox->setIconSize(QSize(60,60));
    templateBox->clear();
Laurent Montel's avatar
Laurent Montel committed
535
    templateBox->addItem(QString());
Laurent Montel's avatar
Laurent Montel committed
536
    foreach (const TitleTemplate &t, titletemplates) {
537 538
        templateBox->addItem(t.icon, t.name, t.file);
    }
539
    lastDocumentHash = QCryptographicHash::hash(xml().toString().toLatin1(), QCryptographicHash::Md5).toHex();
Marco Gittler's avatar
Marco Gittler committed
540
}
541

542 543
TitleWidget::~TitleWidget()
{
544
    m_scene->blockSignals(true);
545 546 547 548 549 550
    delete m_buttonRect;
    delete m_buttonText;
    delete m_buttonImage;
    delete m_buttonCursor;
    delete m_buttonSave;
    delete m_buttonLoad;
551
    delete m_unicodeAction;
Simon Eugster's avatar
Simon Eugster committed
552 553 554 555
    delete m_zUp;
    delete m_zDown;
    delete m_zTop;
    delete m_zBottom;
556 557 558 559 560
    delete m_selectAll;
    delete m_selectText;
    delete m_selectRects;
    delete m_selectImages;
    delete m_unselectAll;
561

Alberto Villa's avatar
Alberto Villa committed
562
    delete m_unicodeDialog;
563 564
    delete m_frameBorder;
    delete m_frameImage;
565 566
    delete m_startViewport;
    delete m_endViewport;
567
    delete m_scene;
568
    delete m_signalMapper;
569 570
}

571
// static
Laurent Montel's avatar
Laurent Montel committed
572
QStringList TitleWidget::extractImageList(const QString &xml)
573 574
{
    QStringList result;
Laurent Montel's avatar
Laurent Montel committed
575 576 577
    if (xml.isEmpty()) {
        return result;
    }
578 579
    QDomDocument doc;
    doc.setContent(xml);
580
    QDomNodeList images = doc.elementsByTagName(QStringLiteral("content"));
581
    for (int i = 0; i < images.count(); ++i) {
Laurent Montel's avatar
Laurent Montel committed
582
        if (images.at(i).toElement().hasAttribute(QStringLiteral("url"))) {
583
            result.append(images.at(i).toElement().attribute(QStringLiteral("url")));
Laurent Montel's avatar
Laurent Montel committed
584
        }
585 586 587 588
    }
    return result;
}

589
// static
Laurent Montel's avatar
Laurent Montel committed
590
QStringList TitleWidget::extractFontList(const QString &xml)
591 592
{
    QStringList result;
Laurent Montel's avatar
Laurent Montel committed
593 594 595
    if (xml.isEmpty()) {
        return result;
    }
596 597
    QDomDocument doc;
    doc.setContent(xml);
598
    QDomNodeList images = doc.elementsByTagName(QStringLiteral("content"));
599
    for (int i = 0; i < images.count(); ++i) {
Laurent Montel's avatar
Laurent Montel committed
600
        if (images.at(i).toElement().hasAttribute(QStringLiteral("font"))) {
601
            result.append(images.at(i).toElement().attribute(QStringLiteral("font")));
Laurent Montel's avatar
Laurent Montel committed
602
        }
603 604 605
    }
    return result;
}
606
//static
607
void TitleWidget::refreshTitleTemplates(const QString &projectPath)
608
{
Laurent Montel's avatar
Laurent Montel committed
609
    QStringList filters = QStringList() << QStringLiteral("*.kdenlivetitle");
610
    titletemplates.clear();
611 612 613 614

    // project templates
    QDir dir(projectPath);
    QStringList templateFiles = dir.entryList(filters, QDir::Files);
Laurent Montel's avatar
Laurent Montel committed
615
    foreach (const QString &fname, templateFiles) {
616
        TitleTemplate t;
Laurent Montel's avatar
Laurent Montel committed
617 618 619 620
        t.name = fname;
        t.file = dir.absoluteFilePath(fname);
        t.icon = QIcon(KThumb::getImage(QUrl::fromLocalFile(t.file), 0, 60, 60));
        titletemplates.append(t);
621 622 623
    }

    // system templates
624
    QStringList titleTemplates = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("titles/"), QStandardPaths::LocateDirectory);
Laurent Montel's avatar
Laurent Montel committed
625
    foreach (const QString &folderpath, titleTemplates) {
626
        QDir folder(folderpath);
627
        QStringList filesnames = folder.entryList(filters, QDir::Files);
Laurent Montel's avatar
Laurent Montel committed
628
        foreach (const QString &fname, filesnames) {
629 630
            TitleTemplate t;
            t.name = fname;
631 632
            t.file = folder.absoluteFilePath(fname);
            t.icon = QIcon(KThumb::getImage(QUrl::fromLocalFile(t.file), 0, 60, 60));
633
            titletemplates.append(t);
634 635 636
        }
    }
}
Laurent Montel's avatar
Laurent Montel committed
637

638
void TitleWidget::templateIndexChanged(int index)
639
{
640
    QString item = templateBox->itemData(index).toString();
641
    if (!item.isEmpty()) {
642
        if (lastDocumentHash != QCryptographicHash::hash(xml().toString().toLatin1(), QCryptographicHash::Md5).toHex()) {
Laurent Montel's avatar
Laurent Montel committed
643
            if (KMessageBox::questionYesNo(this, i18n("Do you really want to load a new template? Changes in this title will be lost!")) == KMessageBox::No) {
Laurent Montel's avatar
Laurent Montel committed
644
                return;
Laurent Montel's avatar
Laurent Montel committed
645
            }
646
        }
647
        loadTitle(QUrl::fromLocalFile(item));
648 649 650 651

        // mbt 1607: Add property to distinguish between unchanged template titles and user titles.
        // Text of unchanged template titles should be selected when clicked.
        QList<QGraphicsItem *> list = graphicsView->scene()->items();
Laurent Montel's avatar
Laurent Montel committed
652
        foreach (QGraphicsItem *qgItem, list) {
653
            if (qgItem->type() == TEXTITEM) {
654
                MyTextItem *i = static_cast<MyTextItem *>(qgItem);
655 656 657 658 659
                i->setProperty("isTemplate", "true");
                i->setProperty("templateText", i->toHtml());
            }

        }
660
        lastDocumentHash = QCryptographicHash::hash(xml().toString().toLatin1(), QCryptographicHash::Md5).toHex();
661
    }
662
}
663
//virtual
664 665
void TitleWidget::resizeEvent(QResizeEvent * /*event*/)
{
666
    //slotAdjustZoom();
667
}
668
//virtual
Laurent Montel's avatar
Laurent Montel committed
669 670
void TitleWidget::keyPressEvent(QKeyEvent *e)
{
Laurent Montel's avatar
Laurent Montel committed
671 672 673
    if (e->key() != Qt::Key_Escape && e->key() != Qt::Key_Return && e->key() != Qt::Key_Enter) {
        QDialog::keyPressEvent(e);
    }
674
}
Laurent Montel's avatar
Laurent Montel committed
675

676 677
void TitleWidget::slotTextTool()
{
678
    m_scene->setTool(TITLE_TEXT);
Simon Eugster's avatar
Simon Eugster committed
679
    showToolbars(TITLE_TEXT);
Simon Eugster's avatar
Simon Eugster committed
680
    checkButton(TITLE_TEXT);
681 682
}

683 684
void TitleWidget::slotRectTool()
{
685
    m_scene->setTool(TITLE_RECTANGLE);
Simon Eugster's avatar
Simon Eugster committed
686
    showToolbars(TITLE_RECTANGLE);
Simon Eugster's avatar
Simon Eugster committed
687
    checkButton(TITLE_RECTANGLE);
688

689 690
    // Disable dragging mode, would make dragging a rect impossible otherwise ;)
    graphicsView->setDragMode(QGraphicsView::NoDrag);
691 692
}

693 694
void TitleWidget::slotSelectTool()
{
695
    m_scene->setTool(TITLE_SELECT);
696

697 698
    // Enable rubberband selecting mode.
    graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
Simon Eugster's avatar
Simon Eugster committed
699 700 701 702

    // Find out which toolbars need to be shown, depending on selected item
    TITLETOOL t = TITLE_SELECT;
    QList<QGraphicsItem *> l = graphicsView->scene()->selectedItems();
Laurent Montel's avatar
Laurent Montel committed
703
    if (!l.isEmpty()) {
704
        switch (l.at(0)->type()) {
Simon Eugster's avatar
Simon Eugster committed
705 706 707 708 709 710 711 712 713 714 715
        case TEXTITEM:
            t = TITLE_TEXT;
            break;
        case RECTITEM:
            t = TITLE_RECTANGLE;
            break;
        case IMAGEITEM:
            t = TITLE_IMAGE;
            break;
        }
    }
716

Simon Eugster's avatar
Simon Eugster committed
717
    enableToolbars(t);
718
    if (t == TITLE_RECTANGLE && (l.at(0) == m_endViewport || l.at(0) == m_startViewport)) {
719
        //graphicsView->centerOn(l.at(0));
720
        t = TITLE_SELECT;
721
    }
Simon Eugster's avatar
Simon Eugster committed
722 723
    showToolbars(t);

Laurent Montel's avatar
Laurent Montel committed
724
    if (!l.isEmpty()) {
725 726 727 728 729
        updateCoordinates(l.at(0));
        updateDimension(l.at(0));
        updateRotZoom(l.at(0));
    }

Simon Eugster's avatar
Simon Eugster committed
730
    checkButton(TITLE_SELECT);
731 732
}

733 734
void TitleWidget::slotImageTool()
{
735 736
    QList<QByteArray> supported = QImageReader::supportedImageFormats();
    QStringList mimeTypeFilters;
Laurent Montel's avatar
Laurent Montel committed
737
    QString allExtensions = i18n("All Images") + QStringLiteral(" (");
738
    foreach (const QByteArray &mimeType, supported) {
Laurent Montel's avatar
Laurent Montel committed
739
        mimeTypeFilters.append(i18n("%1 Image", QString(mimeType)) + QStringLiteral("( *.") + QString(mimeType) + QLatin1Char(')'));
Laurent Montel's avatar
Laurent Montel committed
740
        allExtensions.append(QStringLiteral("*.") + mimeType + QLatin1Char(' '));
741 742
    }
    mimeTypeFilters.sort();
Laurent Montel's avatar
Laurent Montel committed
743
    allExtensions.append(QLatin1Char(')'));
744
    mimeTypeFilters.prepend(allExtensions);
745
    QString clipFolder = KRecentDirs::dir(QStringLiteral(":KdenliveImageFolder"));
746 747 748 749 750 751
    if (clipFolder.isEmpty()) {
        clipFolder = QDir::homePath();
    }
    QFileDialog dialog(this, i18n("Add Image"), clipFolder);
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
    dialog.setNameFilters(mimeTypeFilters);
Laurent Montel's avatar
Laurent Montel committed
752 753 754
    if (dialog.exec() != QDialog::Accepted) {
        return;
    }
755
    QUrl url = QUrl::fromLocalFile(dialog.selectedFiles().at(0));
756
    if (url.isValid()) {
757 758
        KRecentDirs::add(QStringLiteral(":KdenliveImageFolder"), url.adjusted(QUrl::RemoveFilename).toLocalFile());
        if (url.toLocalFile().endsWith(QLatin1String(".svg"))) {
759 760
            MySvgItem *svg = new MySvgItem(url.toLocalFile());
            svg->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
761
            svg->setZValue(m_count++);
762
            svg->setData(Qt::UserRole, url.toLocalFile());
763
            m_scene->addNewItem(svg);
Laurent Montel's avatar
Laurent Montel committed
764
            prepareTools(svg);
765
        } else {
766
            QPixmap pix(url.toLocalFile());
767
            MyPixmapItem *image = new MyPixmapItem(pix);
768
            image->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
769
            image->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
770
            image->setData(Qt::UserRole, url.toLocalFile());
771
            image->setZValue(m_count++);
772
            m_scene->addNewItem(image);
Laurent Montel's avatar
Laurent Montel committed
773
            prepareTools(image);
774 775 776
        }
    }
    m_scene->setTool(TITLE_SELECT);
Simon Eugster's avatar
Simon Eugster committed
777
    showToolbars(TITLE_SELECT);
778
    checkButton(TITLE_SELECT);
779 780
}

Simon Eugster's avatar
Simon Eugster committed
781 782
void TitleWidget::showToolbars(TITLETOOL toolType)
{
783
    //toolbar_stack->setEnabled(toolType != TITLE_SELECT);
784
    switch (toolType) {
785
    case TITLE_IMAGE:
786
        toolbar_stack->setCurrentIndex(2);
787 788 789 790 791
        break;
    case TITLE_RECTANGLE:
        toolbar_stack->setCurrentIndex(1);
        break;
    case TITLE_TEXT:
792 793
    default:
        toolbar_stack->setCurrentIndex(0);
794
        break;