]> git.sesse.net Git - kdenlive/blob - src/titlewidget.cpp
http://www.kdenlive.org/mantis/view.php?id=1243
[kdenlive] / src / titlewidget.cpp
1 /***************************************************************************
2                           titlewidget.cpp  -  description
3                              -------------------
4     begin                : Feb 28 2008
5     copyright            : (C) 2008 by Marco Gittler
6     email                : g.marco@freenet.de
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17
18 #include "titlewidget.h"
19 #include "kdenlivesettings.h"
20
21 #include <cmath>
22
23 #include <KDebug>
24 #include <KGlobalSettings>
25 #include <KFileDialog>
26 #include <KStandardDirs>
27 #include <KMessageBox>
28 #include <kio/netaccess.h>
29 #include <kdeversion.h>
30
31 #include <QDomDocument>
32 #include <QGraphicsItem>
33 #include <QGraphicsSvgItem>
34 #include <QTimer>
35 #include <QToolBar>
36 #include <QMenu>
37 #include <QSignalMapper>
38 #include <QTextBlockFormat>
39 #include <QTextCursor>
40
41 #if QT_VERSION >= 0x040600
42 #include <QGraphicsEffect>
43 #include <QGraphicsBlurEffect>
44 #include <QGraphicsDropShadowEffect>
45 #endif
46
47 int settingUp = false;
48
49 const int IMAGEITEM = 7;
50 const int RECTITEM = 3;
51 const int TEXTITEM = 8;
52
53 TitleWidget::TitleWidget(KUrl url, Timecode tc, QString projectTitlePath, Render *render, QWidget *parent) :
54         QDialog(parent),
55         Ui::TitleWidget_UI(),
56         m_startViewport(NULL),
57         m_endViewport(NULL),
58         m_render(render),
59         m_count(0),
60         m_unicodeDialog(new UnicodeDialog(UnicodeDialog::InputHex)),
61         m_projectTitlePath(projectTitlePath),
62         m_tc(tc)
63 {
64     setupUi(this);
65     setFont(KGlobalSettings::toolBarFont());
66     frame_properties->setEnabled(false);
67     rect_properties->setFixedHeight(frame_properties->height() + 4);
68     no_properties->setFixedHeight(frame_properties->height() + 4);
69     image_properties->setFixedHeight(frame_properties->height() + 4);
70     text_properties->setFixedHeight(frame_properties->height() + 4);
71     frame_properties->setFixedHeight(frame_toolbar->height());
72
73     itemzoom->setSuffix(i18n("%"));
74     m_frameWidth = render->renderWidth();
75     m_frameHeight = render->renderHeight();
76     showToolbars(TITLE_NONE);
77
78     //TODO: get default title duration instead of hardcoded one
79     title_duration->setText(m_tc.getTimecode(GenTime(5000 / 1000.0)));
80
81     connect(kcolorbutton, SIGNAL(clicked()), this, SLOT(slotChangeBackground())) ;
82     connect(horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChangeBackground())) ;
83
84     connect(fontColorButton, SIGNAL(clicked()), this, SLOT(slotUpdateText())) ;
85     connect(font_family, SIGNAL(currentFontChanged(const QFont &)), this, SLOT(slotUpdateText())) ;
86     connect(font_size, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText())) ;
87     connect(textAlpha, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText()));
88     connect(font_weight_box, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateText()));
89
90     connect(font_family, SIGNAL(editTextChanged(const QString &)), this, SLOT(slotFontText(const QString&)));
91
92     connect(rectFAlpha, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
93     connect(rectBAlpha, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
94     connect(rectFColor, SIGNAL(clicked()), this, SLOT(rectChanged()));
95     connect(rectBColor, SIGNAL(clicked()), this, SLOT(rectChanged()));
96     connect(rectLineWidth, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
97
98     /*connect(startViewportX, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
99     connect(startViewportY, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
100     connect(startViewportSize, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
101     connect(endViewportX, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
102     connect(endViewportY, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
103     connect(endViewportSize, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));*/
104
105     connect(zValue, SIGNAL(valueChanged(int)), this, SLOT(zIndexChanged(int)));
106     connect(itemzoom, SIGNAL(valueChanged(int)), this, SLOT(itemScaled(int)));
107     connect(itemrotate, SIGNAL(valueChanged(int)), this, SLOT(itemRotate(int)));
108     connect(itemhcenter, SIGNAL(clicked()), this, SLOT(itemHCenter()));
109     connect(itemvcenter, SIGNAL(clicked()), this, SLOT(itemVCenter()));
110     connect(itemtop, SIGNAL(clicked()), this, SLOT(itemTop()));
111     connect(itembottom, SIGNAL(clicked()), this, SLOT(itemBottom()));
112     connect(itemleft, SIGNAL(clicked()), this, SLOT(itemLeft()));
113     connect(itemright, SIGNAL(clicked()), this, SLOT(itemRight()));
114     connect(effect_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotAddEffect(int)));
115     connect(blur_radius, SIGNAL(valueChanged(int)), this, SLOT(slotEditBlur(int)));
116     connect(shadow_radius, SIGNAL(valueChanged(int)), this, SLOT(slotEditShadow()));
117     connect(shadow_x, SIGNAL(valueChanged(int)), this, SLOT(slotEditShadow()));
118     connect(shadow_y, SIGNAL(valueChanged(int)), this, SLOT(slotEditShadow()));
119     blur_frame->setHidden(true);
120     shadow_frame->setHidden(true);
121
122     connect(origin_x_left, SIGNAL(clicked()), this, SLOT(slotOriginXClicked()));
123     connect(origin_y_top, SIGNAL(clicked()), this, SLOT(slotOriginYClicked()));
124
125     m_signalMapper = new QSignalMapper(this);
126     m_signalMapper->setMapping(value_w, ValueWidth);
127     m_signalMapper->setMapping(value_h, ValueHeight);
128     connect(value_w, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
129     connect(value_h, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
130     connect(m_signalMapper, SIGNAL(mapped(int)), this, SLOT(slotValueChanged(int)));
131
132     connect(value_x, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
133     connect(value_y, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
134     connect(value_w, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
135     connect(value_h, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
136     connect(buttonFitZoom, SIGNAL(clicked()), this, SLOT(slotAdjustZoom()));
137     connect(buttonRealSize, SIGNAL(clicked()), this, SLOT(slotZoomOneToOne()));
138     connect(buttonItalic, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
139     connect(buttonUnder, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
140     connect(buttonAlignLeft, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
141     connect(buttonAlignRight, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
142     connect(buttonAlignCenter, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
143     connect(buttonAlignNone, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
144     //connect(buttonInsertUnicode, SIGNAL(clicked()), this, SLOT(slotInsertUnicode()));
145     connect(displayBg, SIGNAL(stateChanged(int)), this, SLOT(displayBackgroundFrame()));
146
147     connect(m_unicodeDialog, SIGNAL(charSelected(QString)), this, SLOT(slotInsertUnicodeString(QString)));
148
149     // mbd
150     connect(this, SIGNAL(accepted()), this, SLOT(slotAccepted()));
151
152     font_weight_box->blockSignals(true);
153     font_weight_box->addItem(i18nc("Font style", "Light"), QFont::Light);
154     font_weight_box->addItem(i18nc("Font style", "Normal"), QFont::Normal);
155     font_weight_box->addItem(i18nc("Font style", "Demi-Bold"), QFont::DemiBold);
156     font_weight_box->addItem(i18nc("Font style", "Bold"), QFont::Bold);
157     font_weight_box->addItem(i18nc("Font style", "Black"), QFont::Black);
158     font_weight_box->setToolTip(i18n("Font weight"));
159     font_weight_box->setCurrentIndex(1);
160     font_weight_box->blockSignals(false);
161
162     buttonFitZoom->setIcon(KIcon("zoom-fit-best"));
163     buttonRealSize->setIcon(KIcon("zoom-original"));
164     buttonItalic->setIcon(KIcon("format-text-italic"));
165     buttonUnder->setIcon(KIcon("format-text-underline"));
166     buttonAlignCenter->setIcon(KIcon("format-justify-center"));
167     buttonAlignLeft->setIcon(KIcon("format-justify-left"));
168     buttonAlignRight->setIcon(KIcon("format-justify-right"));
169     buttonAlignNone->setIcon(KIcon("kdenlive-align-none"));
170
171     buttonAlignNone->setToolTip(i18n("No alignment"));
172     buttonAlignRight->setToolTip(i18n("Align right"));
173     buttonAlignLeft->setToolTip(i18n("Align left"));
174     buttonAlignCenter->setToolTip(i18n("Align center"));
175
176     m_unicodeAction = new QAction(KIcon("kdenlive-insert-unicode"), QString(), this);
177     m_unicodeAction->setShortcut(Qt::SHIFT + Qt::CTRL + Qt::Key_U);
178     m_unicodeAction->setToolTip(i18n("Insert Unicode character") + ' ' + m_unicodeAction->shortcut().toString());
179     connect(m_unicodeAction, SIGNAL(triggered()), this, SLOT(slotInsertUnicode()));
180     buttonInsertUnicode->setDefaultAction(m_unicodeAction);
181
182     origin_x_left->setToolTip(i18n("Invert x axis and change 0 point"));
183     origin_y_top->setToolTip(i18n("Invert y axis and change 0 point"));
184     rectBColor->setToolTip(i18n("Select fill color"));
185     rectFColor->setToolTip(i18n("Select border color"));
186     rectBAlpha->setToolTip(i18n("Fill transparency"));
187     rectFAlpha->setToolTip(i18n("Border transparency"));
188     zoom_slider->setToolTip(i18n("Zoom"));
189     buttonRealSize->setToolTip(i18n("Original size (1:1)"));
190     buttonFitZoom->setToolTip(i18n("Fit zoom"));
191     kcolorbutton->setToolTip(i18n("Select background color"));
192     horizontalSlider->setToolTip(i18n("Background Transparency"));
193
194     itemhcenter->setIcon(KIcon("kdenlive-align-hor"));
195     itemhcenter->setToolTip(i18n("Align item horizontally"));
196     itemvcenter->setIcon(KIcon("kdenlive-align-vert"));
197     itemvcenter->setToolTip(i18n("Align item vertically"));
198     itemtop->setIcon(KIcon("kdenlive-align-top"));
199     itemtop->setToolTip(i18n("Align item to top"));
200     itembottom->setIcon(KIcon("kdenlive-align-bottom"));
201     itembottom->setToolTip(i18n("Align item to bottom"));
202     itemright->setIcon(KIcon("kdenlive-align-right"));
203     itemright->setToolTip(i18n("Align item to right"));
204     itemleft->setIcon(KIcon("kdenlive-align-left"));
205     itemleft->setToolTip(i18n("Align item to left"));
206
207
208     QHBoxLayout *layout = new QHBoxLayout;
209     frame_toolbar->setLayout(layout);
210     layout->setContentsMargins(2, 2, 2, 2);
211     QToolBar *m_toolbar = new QToolBar("titleToolBar", this);
212
213     m_buttonCursor = m_toolbar->addAction(KIcon("transform-move"), QString());
214     m_buttonCursor->setCheckable(true);
215     m_buttonCursor->setShortcut(Qt::ALT + Qt::Key_S);
216     m_buttonCursor->setToolTip(i18n("Selection Tool") + ' ' + m_buttonCursor->shortcut().toString());
217     connect(m_buttonCursor, SIGNAL(triggered()), this, SLOT(slotSelectTool()));
218
219     m_buttonText = m_toolbar->addAction(KIcon("insert-text"), QString());
220     m_buttonText->setCheckable(true);
221     m_buttonText->setShortcut(Qt::ALT + Qt::Key_T);
222     m_buttonText->setToolTip(i18n("Add Text") + ' ' + m_buttonText->shortcut().toString());
223     connect(m_buttonText, SIGNAL(triggered()), this, SLOT(slotTextTool()));
224
225     m_buttonRect = m_toolbar->addAction(KIcon("kdenlive-insert-rect"), QString());
226     m_buttonRect->setCheckable(true);
227     m_buttonRect->setShortcut(Qt::ALT + Qt::Key_R);
228     m_buttonRect->setToolTip(i18n("Add Rectangle") + ' ' + m_buttonRect->shortcut().toString());
229     connect(m_buttonRect, SIGNAL(triggered()), this, SLOT(slotRectTool()));
230
231     m_buttonImage = m_toolbar->addAction(KIcon("insert-image"), QString());
232     m_buttonImage->setCheckable(false);
233     m_buttonImage->setShortcut(Qt::ALT + Qt::Key_I);
234     m_buttonImage->setToolTip(i18n("Add Image") + ' ' + m_buttonImage->shortcut().toString());
235     connect(m_buttonImage, SIGNAL(triggered()), this, SLOT(slotImageTool()));
236
237     m_toolbar->addSeparator();
238
239     m_buttonLoad = m_toolbar->addAction(KIcon("document-open"), i18n("Open Document"));
240     m_buttonLoad->setCheckable(false);
241     m_buttonLoad->setShortcut(Qt::CTRL + Qt::Key_O);
242     connect(m_buttonLoad, SIGNAL(triggered()), this, SLOT(loadTitle()));
243
244     m_buttonSave = m_toolbar->addAction(KIcon("document-save-as"), i18n("Save As"));
245     m_buttonSave->setCheckable(false);
246     m_buttonSave->setShortcut(Qt::CTRL + Qt::Key_S);
247     connect(m_buttonSave, SIGNAL(triggered()), this, SLOT(saveTitle()));
248
249     layout->addWidget(m_toolbar);
250
251     // initialize graphic scene
252     m_scene = new GraphicsSceneRectMove(this);
253     graphicsView->setScene(m_scene);
254     m_titledocument.setScene(m_scene, m_frameWidth, m_frameHeight);
255     connect(m_scene, SIGNAL(changed(QList<QRectF>)), this, SLOT(slotChanged()));
256
257     // a gradient background
258     /*QRadialGradient *gradient = new QRadialGradient(0, 0, 10);
259     gradient->setSpread(QGradient::ReflectSpread);
260     scene->setBackgroundBrush(*gradient);*/
261
262     m_frameImage = new QGraphicsPixmapItem();
263     QTransform qtrans;
264     qtrans.scale(2.0, 2.0);
265     m_frameImage->setTransform(qtrans);
266     m_frameImage->setZValue(-1200);
267     m_frameImage->setFlags(0);
268     displayBackgroundFrame();
269     graphicsView->scene()->addItem(m_frameImage);
270
271     connect(m_scene, SIGNAL(selectionChanged()), this , SLOT(selectionChanged()));
272     connect(m_scene, SIGNAL(itemMoved()), this , SLOT(selectionChanged()));
273     connect(m_scene, SIGNAL(sceneZoom(bool)), this , SLOT(slotZoom(bool)));
274     connect(m_scene, SIGNAL(actionFinished()), this , SLOT(slotSelectTool()));
275     //connect(m_scene, SIGNAL(actionFinished()), this , SLOT(selectionChanged()));
276     connect(m_scene, SIGNAL(newRect(QGraphicsRectItem *)), this , SLOT(slotNewRect(QGraphicsRectItem *)));
277     connect(m_scene, SIGNAL(newText(QGraphicsTextItem *)), this , SLOT(slotNewText(QGraphicsTextItem *)));
278     connect(zoom_slider, SIGNAL(valueChanged(int)), this , SLOT(slotUpdateZoom(int)));
279
280     QPen framepen(Qt::DotLine);
281     framepen.setColor(Qt::red);
282
283     m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
284     m_frameBorder->setPen(framepen);
285     m_frameBorder->setZValue(-1100);
286     m_frameBorder->setBrush(Qt::transparent);
287     m_frameBorder->setFlags(0);
288     graphicsView->scene()->addItem(m_frameBorder);
289
290     // mbd: load saved settings
291     readChoices();
292
293     graphicsView->show();
294     //graphicsView->setRenderHint(QPainter::Antialiasing);
295     graphicsView->setInteractive(true);
296     //graphicsView->resize(400, 300);
297     kDebug() << "// TITLE WIDGWT: " << graphicsView->viewport()->width() << "x" << graphicsView->viewport()->height();
298     //toolBox->setItemEnabled(2, false);
299     m_startViewport = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
300     m_endViewport = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
301     m_startViewport->setData(0, m_frameWidth);
302     m_startViewport->setData(1, m_frameHeight);
303     m_endViewport->setData(0, m_frameWidth);
304     m_endViewport->setData(1, m_frameHeight);
305
306     if (!url.isEmpty()) loadTitle(url);
307     else {
308         slotTextTool();
309         QTimer::singleShot(200, this, SLOT(slotAdjustZoom()));
310     }
311     initAnimation();
312     connect(anim_start, SIGNAL(toggled(bool)), this, SLOT(slotAnimStart(bool)));
313     connect(anim_end, SIGNAL(toggled(bool)), this, SLOT(slotAnimEnd(bool)));
314
315     buttonBox->button(QDialogButtonBox::Ok)->setEnabled(KdenliveSettings::hastitleproducer());
316 }
317
318 TitleWidget::~TitleWidget()
319 {
320     delete m_buttonRect;
321     delete m_buttonText;
322     delete m_buttonImage;
323     delete m_buttonCursor;
324     delete m_buttonSave;
325     delete m_buttonLoad;
326     delete m_unicodeAction;
327
328     delete m_unicodeDialog;
329     delete m_frameBorder;
330     delete m_frameImage;
331     delete m_startViewport;
332     delete m_endViewport;
333     delete m_scene;
334     delete m_signalMapper;
335 }
336
337 //static
338 QStringList TitleWidget::getFreeTitleInfo(const KUrl &projectUrl, bool isClone)
339 {
340     QStringList result;
341     QString titlePath = projectUrl.path(KUrl::AddTrailingSlash) + "titles/";
342     KStandardDirs::makeDir(titlePath);
343     titlePath.append((isClone == false) ? "title" : "clone");
344     int counter = 0;
345     QString path;
346     while (path.isEmpty() || QFile::exists(path)) {
347         counter++;
348         path = titlePath + QString::number(counter).rightJustified(3, '0', false) + ".png";
349     }
350     result.append(((isClone == false) ? i18n("Title") : i18n("Clone")) + ' ' + QString::number(counter).rightJustified(3, '0', false));
351     result.append(path);
352     return result;
353 }
354
355 // static
356 QString TitleWidget::getTitleResourceFromName(const KUrl &projectUrl, const QString &titleName)
357 {
358     QStringList result;
359     QString titlePath = projectUrl.path(KUrl::AddTrailingSlash) + "titles/";
360     KStandardDirs::makeDir(titlePath);
361     return titlePath + titleName + ".png";
362 }
363
364 // static
365 QStringList TitleWidget::extractImageList(QString xml)
366 {
367     QStringList result;
368     if (xml.isEmpty()) return result;
369     QDomDocument doc;
370     doc.setContent(xml);
371     QDomNodeList images = doc.elementsByTagName("content");
372     for (int i = 0; i < images.count(); i++) {
373         if (images.at(i).toElement().hasAttribute("url"))
374             result.append(images.at(i).toElement().attribute("url"));
375     }
376     return result;
377 }
378
379
380 //virtual
381 void TitleWidget::resizeEvent(QResizeEvent * /*event*/)
382 {
383     //slotAdjustZoom();
384 }
385
386 void TitleWidget::slotTextTool()
387 {
388     m_scene->setTool(TITLE_TEXT);
389     showToolbars(TITLE_TEXT);
390     checkButton(TITLE_TEXT);
391 }
392
393 void TitleWidget::slotRectTool()
394 {
395     m_scene->setTool(TITLE_RECTANGLE);
396     showToolbars(TITLE_RECTANGLE);
397     checkButton(TITLE_RECTANGLE);
398 }
399
400 void TitleWidget::slotSelectTool()
401 {
402     m_scene->setTool(TITLE_SELECT);
403
404     // Find out which toolbars need to be shown, depending on selected item
405     TITLETOOL t = TITLE_SELECT;
406     QList<QGraphicsItem *> l = graphicsView->scene()->selectedItems();
407     if (l.size() > 0) {
408         switch (l.at(0)->type()) {
409         case TEXTITEM:
410             t = TITLE_TEXT;
411             break;
412         case RECTITEM:
413             t = TITLE_RECTANGLE;
414             break;
415         case IMAGEITEM:
416             t = TITLE_IMAGE;
417             break;
418         }
419     }
420
421     enableToolbars(t);
422     if (t == TITLE_RECTANGLE && (l.at(0) == m_endViewport || l.at(0) == m_startViewport)) {
423         //graphicsView->centerOn(l.at(0));
424         t = TITLE_NONE;
425     }
426     showToolbars(t);
427
428     if (l.size() > 0) {
429         updateCoordinates(l.at(0));
430         updateDimension(l.at(0));
431         updateRotZoom(l.at(0));
432     }
433
434     checkButton(TITLE_SELECT);
435 }
436
437 void TitleWidget::slotImageTool()
438 {
439     // TODO: find a way to get a list of all supported image types...
440     QString allExtensions = "image/gif image/jpeg image/png image/x-tga image/x-bmp image/svg+xml image/tiff image/x-xcf-gimp image/x-vnd.adobe.photoshop image/x-pcx image/x-exr";
441     KUrl url = KFileDialog::getOpenUrl(KUrl(), allExtensions, this, i18n("Load Image")); //"*.svg *.png *.jpg *.jpeg *.gif *.raw"
442     if (!url.isEmpty()) {
443         if (url.path().endsWith(".svg")) {
444             QGraphicsSvgItem *svg = new QGraphicsSvgItem(url.toLocalFile());
445             svg->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
446             svg->setZValue(m_count++);
447             svg->setData(Qt::UserRole, url.path());
448             graphicsView->scene()->addItem(svg);
449         } else {
450             QPixmap pix(url.path());
451             QGraphicsPixmapItem *image = new QGraphicsPixmapItem(pix);
452             image->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
453             image->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
454             image->setData(Qt::UserRole, url.path());
455             image->setZValue(m_count++);
456             graphicsView->scene()->addItem(image);
457         }
458     }
459     m_scene->setTool(TITLE_SELECT);
460     showToolbars(TITLE_SELECT);
461     checkButton(TITLE_NONE);
462 }
463
464 void TitleWidget::showToolbars(TITLETOOL toolType)
465 {
466     switch (toolType) {
467     case TITLE_TEXT:
468         rect_properties->setHidden(true);
469         image_properties->setHidden(true);
470         no_properties->setHidden(true);
471         text_properties->setHidden(false);
472         break;
473     case TITLE_RECTANGLE:
474         image_properties->setHidden(true);
475         no_properties->setHidden(true);
476         text_properties->setHidden(true);
477         rect_properties->setHidden(false);
478         break;
479     case TITLE_IMAGE:
480         no_properties->setHidden(true);
481         text_properties->setHidden(true);
482         rect_properties->setHidden(true);
483         image_properties->setHidden(false);
484         break;
485     default:
486         text_properties->setHidden(true);
487         rect_properties->setHidden(true);
488         image_properties->setHidden(true);
489         no_properties->setHidden(false);
490         break;
491     }
492 }
493
494 void TitleWidget::enableToolbars(TITLETOOL toolType)
495 {
496     // TITLETOOL is defined in graphicsscenerectmove.h
497     bool bFrame = false;
498     bool bText = false;
499     bool bRect = false;
500     bool bImage = false;
501     bool bValue_w = false;
502     bool bValue_h = false;
503
504     switch (toolType) {
505     case TITLE_SELECT:
506         break;
507     case TITLE_TEXT:
508         bFrame = true;
509         bText = true;
510         break;
511     case TITLE_RECTANGLE:
512         bFrame = true;
513         bRect = true;
514         bValue_w = true;
515         bValue_h = true;
516         break;
517     case TITLE_IMAGE:
518         bFrame = true;
519         bValue_w = true;
520         bValue_h = true;
521         bImage = true;
522         break;
523     default:
524         break;
525     }
526     frame_properties->setEnabled(bFrame);
527     text_properties->setEnabled(bText);
528     rect_properties->setEnabled(bRect);
529     image_properties->setEnabled(bImage);
530     value_w->setEnabled(bValue_w);
531     value_h->setEnabled(bValue_h);
532 }
533
534 void TitleWidget::checkButton(TITLETOOL toolType)
535 {
536     bool bSelect = false;
537     bool bText = false;
538     bool bRect = false;
539     bool bImage = false;
540
541     switch (toolType) {
542     case TITLE_SELECT:
543         bSelect = true;
544         break;
545     case TITLE_TEXT:
546         bText = true;
547         break;
548     case TITLE_RECTANGLE:
549         bRect = true;
550         break;
551     case TITLE_IMAGE:
552         bImage = true;
553         break;
554     case TITLE_NONE:
555         break;
556     }
557
558     m_buttonCursor->setChecked(bSelect);
559     m_buttonText->setChecked(bText);
560     m_buttonRect->setChecked(bRect);
561     m_buttonImage->setChecked(bImage);
562 }
563
564 void TitleWidget::displayBackgroundFrame()
565 {
566     if (!displayBg->isChecked()) {
567         QPixmap bg(m_frameWidth / 2, m_frameHeight / 2);
568         QPixmap pattern(20, 20);
569         pattern.fill();
570         QColor bgcolor(210, 210, 210);
571         QPainter p;
572         p.begin(&pattern);
573         p.fillRect(QRect(0, 0, 10, 10), bgcolor);
574         p.fillRect(QRect(10, 10, 20, 20), bgcolor);
575         p.end();
576         QBrush br(pattern);
577
578         p.begin(&bg);
579         p.fillRect(bg.rect(), br);
580         p.end();
581         m_frameImage->setPixmap(bg);
582     } else {
583         m_frameImage->setPixmap(QPixmap::fromImage(m_render->extractFrame((int) m_render->seekPosition().frames(m_render->fps()), m_frameWidth / 2, m_frameHeight / 2)));
584     }
585 }
586
587 void TitleWidget::initAnimation()
588 {
589     align_box->setEnabled(false);
590     QPen startpen(Qt::DotLine);
591     QPen endpen(Qt::DashDotLine);
592     startpen.setColor(QColor(100, 200, 100, 140));
593     endpen.setColor(QColor(200, 100, 100, 140));
594
595     m_startViewport->setPen(startpen);
596     m_endViewport->setPen(endpen);
597
598     m_startViewport->setZValue(-1000);
599     m_endViewport->setZValue(-1000);
600
601     m_startViewport->setFlags(0);
602     m_endViewport->setFlags(0);
603
604     graphicsView->scene()->addItem(m_startViewport);
605     graphicsView->scene()->addItem(m_endViewport);
606
607     connect(keep_aspect, SIGNAL(toggled(bool)), this, SLOT(slotKeepAspect(bool)));
608     connect(resize50, SIGNAL(clicked()), this, SLOT(slotResize50()));
609     connect(resize100, SIGNAL(clicked()), this, SLOT(slotResize100()));
610     connect(resize200, SIGNAL(clicked()), this, SLOT(slotResize200()));
611 }
612
613 void TitleWidget::slotUpdateZoom(int pos)
614 {
615     m_scene->setZoom((double) pos / 100);
616     zoom_label->setText(QString::number(pos) + '%');
617 }
618
619 void TitleWidget::slotZoom(bool up)
620 {
621     int pos = zoom_slider->value();
622     if (up) pos++;
623     else pos--;
624     zoom_slider->setValue(pos);
625 }
626
627 void TitleWidget::slotAdjustZoom()
628 {
629     /*double scalex = graphicsView->width() / (double)(m_frameWidth * 1.2);
630     double scaley = graphicsView->height() / (double)(m_frameHeight * 1.2);
631     if (scalex > scaley) scalex = scaley;
632     int zoompos = (int)(scalex * 7 + 0.5);*/
633     graphicsView->fitInView(m_frameBorder, Qt::KeepAspectRatio);
634     int zoompos = graphicsView->matrix().m11() * 100;
635     zoom_slider->setValue(zoompos);
636     graphicsView->centerOn(m_frameBorder);
637 }
638
639 void TitleWidget::slotZoomOneToOne()
640 {
641     zoom_slider->setValue(100);
642     graphicsView->centerOn(m_frameBorder);
643 }
644
645 void TitleWidget::slotNewRect(QGraphicsRectItem * rect)
646 {
647     updateAxisButtons(rect); // back to default
648
649     QColor f = rectFColor->color();
650     f.setAlpha(rectFAlpha->value());
651     QPen penf(f);
652     penf.setWidth(rectLineWidth->value());
653     rect->setPen(penf);
654     QColor b = rectBColor->color();
655     b.setAlpha(rectBAlpha->value());
656     rect->setBrush(QBrush(b));
657     rect->setZValue(m_count++);
658     //setCurrentItem(rect);
659     //graphicsView->setFocus();
660 }
661
662 void TitleWidget::slotNewText(QGraphicsTextItem *tt)
663 {
664     updateAxisButtons(tt); // back to default
665
666     QFont font = font_family->currentFont();
667     font.setPixelSize(font_size->value());
668     // mbd: issue 551:
669     font.setWeight(font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
670     font.setItalic(buttonItalic->isChecked());
671     font.setUnderline(buttonUnder->isChecked());
672
673     tt->setFont(font);
674     QColor color = fontColorButton->color();
675     color.setAlpha(textAlpha->value());
676     tt->setDefaultTextColor(color);
677     tt->setZValue(m_count++);
678     setCurrentItem(tt);
679 }
680
681 void TitleWidget::setFontBoxWeight(int weight)
682 {
683     int index = font_weight_box->findData(weight);
684     if (index < 0) {
685         index = font_weight_box->findData(QFont::Normal);
686     }
687     font_weight_box->setCurrentIndex(index);
688 }
689
690 void TitleWidget::setCurrentItem(QGraphicsItem *item)
691 {
692     m_scene->setSelectedItem(item);
693 }
694
695 void TitleWidget::zIndexChanged(int v)
696 {
697     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
698     if (l.size() >= 1) {
699         l[0]->setZValue(v);
700     }
701 }
702
703 void TitleWidget::selectionChanged()
704 {
705     if (m_scene->tool() != TITLE_SELECT) return;
706     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
707     //toolBox->setItemEnabled(2, false);
708     //toolBox->setItemEnabled(3, false);
709     value_x->blockSignals(true);
710     value_y->blockSignals(true);
711     value_w->blockSignals(true);
712     value_h->blockSignals(true);
713     itemzoom->blockSignals(true);
714     itemrotate->blockSignals(true);
715     if (l.size() == 0) {
716         bool blockX = !origin_x_left->signalsBlocked();
717         bool blockY = !origin_y_top->signalsBlocked();
718         if (blockX) origin_x_left->blockSignals(true);
719         if (blockY) origin_y_top->blockSignals(true);
720         origin_x_left->setChecked(false);
721         origin_y_top->setChecked(false);
722         updateTextOriginX();
723         updateTextOriginY();
724         enableToolbars(TITLE_NONE);
725         if (blockX) origin_x_left->blockSignals(false);
726         if (blockY) origin_y_top->blockSignals(false);
727         itemzoom->setEnabled(false);
728         itemrotate->setEnabled(false);
729     } else if (l.size() == 1) {
730         if (l.at(0) != m_startViewport && l.at(0) != m_endViewport) {
731             itemzoom->setEnabled(true);
732             itemrotate->setEnabled(true);
733         } else {
734             itemzoom->setEnabled(false);
735             itemrotate->setEnabled(false);
736             updateInfoText();
737         }
738         if (l.at(0)->type() == TEXTITEM) {
739             showToolbars(TITLE_TEXT);
740             QGraphicsTextItem* i = static_cast <QGraphicsTextItem *>(l.at(0));
741             //if (l[0]->hasFocus())
742             //toolBox->setCurrentIndex(0);
743             //toolBox->setItemEnabled(2, true);
744             font_size->blockSignals(true);
745             font_family->blockSignals(true);
746             font_weight_box->blockSignals(true);
747             buttonItalic->blockSignals(true);
748             buttonUnder->blockSignals(true);
749             fontColorButton->blockSignals(true);
750             textAlpha->blockSignals(true);
751             buttonAlignLeft->blockSignals(true);
752             buttonAlignRight->blockSignals(true);
753             buttonAlignNone->blockSignals(true);
754             buttonAlignCenter->blockSignals(true);
755
756             QFont font = i->font();
757             font_family->setCurrentFont(font);
758             font_size->setValue(font.pixelSize());
759             buttonItalic->setChecked(font.italic());
760             buttonUnder->setChecked(font.underline());
761             setFontBoxWeight(font.weight());
762
763             QColor color = i->defaultTextColor();
764             fontColorButton->setColor(color);
765             textAlpha->setValue(color.alpha());
766
767             QTextCursor cur = i->textCursor();
768             QTextBlockFormat format = cur.blockFormat();
769             if (i->textWidth() == -1) buttonAlignNone->setChecked(true);
770             else if (format.alignment() == Qt::AlignHCenter) buttonAlignCenter->setChecked(true);
771             else if (format.alignment() == Qt::AlignRight) buttonAlignRight->setChecked(true);
772             else if (format.alignment() == Qt::AlignLeft) buttonAlignLeft->setChecked(true);
773
774             font_size->blockSignals(false);
775             font_family->blockSignals(false);
776             font_weight_box->blockSignals(false);
777             buttonItalic->blockSignals(false);
778             buttonUnder->blockSignals(false);
779             fontColorButton->blockSignals(false);
780             textAlpha->blockSignals(false);
781             buttonAlignLeft->blockSignals(false);
782             buttonAlignRight->blockSignals(false);
783             buttonAlignNone->blockSignals(false);
784             buttonAlignCenter->blockSignals(false);
785
786             updateAxisButtons(i);
787             updateCoordinates(i);
788             updateDimension(i);
789             enableToolbars(TITLE_TEXT);
790
791         } else if ((l.at(0))->type() == RECTITEM) {
792             showToolbars(TITLE_RECTANGLE);
793             settingUp = true;
794             QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(l.at(0));
795             if (rec == m_startViewport || rec == m_endViewport) {
796                 /*toolBox->setCurrentIndex(3);
797                 toolBox->widget(0)->setEnabled(false);
798                 toolBox->widget(1)->setEnabled(false);*/
799                 enableToolbars(TITLE_NONE);
800             } else {
801                 /*toolBox->widget(0)->setEnabled(true);
802                 toolBox->widget(1)->setEnabled(true);
803                 toolBox->setCurrentIndex(0);*/
804                 //toolBox->setItemEnabled(3, true);
805                 rectFAlpha->setValue(rec->pen().color().alpha());
806                 rectBAlpha->setValue(rec->brush().color().alpha());
807                 //kDebug() << rec->brush().color().alpha();
808                 QColor fcol = rec->pen().color();
809                 QColor bcol = rec->brush().color();
810                 //fcol.setAlpha(255);
811                 //bcol.setAlpha(255);
812                 rectFColor->setColor(fcol);
813                 rectBColor->setColor(bcol);
814                 settingUp = false;
815                 rectLineWidth->setValue(rec->pen().width());
816                 enableToolbars(TITLE_RECTANGLE);
817             }
818
819             updateAxisButtons(l.at(0));
820             updateCoordinates(rec);
821             updateDimension(rec);
822
823         } else if (l.at(0)->type() == IMAGEITEM) {
824             showToolbars(TITLE_IMAGE);
825
826             updateCoordinates(l.at(0));
827             updateDimension(l.at(0));
828
829             enableToolbars(TITLE_IMAGE);
830
831         } else {
832             //toolBox->setCurrentIndex(0);
833             showToolbars(TITLE_NONE);
834             enableToolbars(TITLE_NONE);
835             /*frame_properties->setEnabled(false);
836             text_properties->setEnabled(false);
837             rect_properties->setEnabled(false);*/
838         }
839         zValue->setValue((int)l.at(0)->zValue());
840         itemzoom->setValue((int)(m_transformations.value(l.at(0)).scalex * 100.0 + 0.5));
841         itemrotate->setValue((int)(m_transformations.value(l.at(0)).rotate));
842         value_x->blockSignals(false);
843         value_y->blockSignals(false);
844         value_w->blockSignals(false);
845         value_h->blockSignals(false);
846         itemzoom->blockSignals(false);
847         itemrotate->blockSignals(false);
848     }
849 }
850
851 void TitleWidget::slotValueChanged(int type)
852 {
853     QList<QGraphicsItem *> l = graphicsView->scene()->selectedItems();
854     if (l.size() > 0 && l.at(0)->type() == IMAGEITEM) {
855
856         int val = 0;
857         switch (type) {
858         case ValueWidth:
859             val = value_w->value();
860             break;
861         case ValueHeight:
862             val = value_h->value();
863             break;
864         }
865
866         QGraphicsItem *i = l.at(0);
867         Transform t = m_transformations.value(i);
868
869         // Ratio width:height
870         double phi = (double) i->boundingRect().width() / i->boundingRect().height();
871         double alpha = (double) t.rotate / 180.0 * M_PI;
872
873         // New length
874         double length = val;
875
876         // Scaling factor
877         double scale = 1;
878
879         switch (type) {
880         case ValueWidth:
881             // Add 0.5 because otherwise incrementing by 1 might have no effect
882             length = val / (cos(alpha) + 1 / phi * sin(alpha)) + 0.5;
883             scale = length / i->boundingRect().width();
884             break;
885         case ValueHeight:
886             length = val / (phi * sin(alpha) + cos(alpha)) + 0.5;
887             scale = length / i->boundingRect().height();
888             break;
889         }
890
891         t.scalex = scale;
892         t.scaley = scale;
893         QTransform qtrans;
894         qtrans.scale(scale, scale);
895         qtrans.rotate(t.rotate);
896         i->setTransform(qtrans);
897         m_transformations[i] = t;
898
899         updateDimension(i);
900         updateRotZoom(i);
901     }
902 }
903
904 /** \brief Updates position/size of the selected item when a value
905  * of an item (coordinates, size) has changed */
906 void TitleWidget::slotAdjustSelectedItem()
907 {
908     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
909     if (l.size() >= 1) {
910         if (l.at(0)->type() == RECTITEM) {
911             //rect item
912             QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(l.at(0));
913             updatePosition(rec);
914             rec->setRect(QRect(0, 0, value_w->value(), value_h->value()));
915         } else if (l.at(0)->type() == TEXTITEM) {
916             //text item
917             updatePosition(l.at(0));
918         } else if (l.at(0)->type() == IMAGEITEM) {
919             //image item
920             updatePosition(l.at(0));
921         }
922     }
923 }
924
925 /** \brief Updates width/height int the text fields, regarding transformation matrix */
926 void TitleWidget::updateDimension(QGraphicsItem *i)
927 {
928     value_w->blockSignals(true);
929     value_h->blockSignals(true);
930
931
932     if (i->type() == IMAGEITEM) {
933         // Get multipliers for rotation/scaling
934
935         /*Transform t = m_transformations.value(i);
936         QRectF r = i->boundingRect();
937         int width = (int) ( abs(r.width()*t.scalex * cos(t.rotate/180.0*M_PI))
938                     + abs(r.height()*t.scaley * sin(t.rotate/180.0*M_PI)) );
939         int height = (int) ( abs(r.height()*t.scaley * cos(t.rotate/180*M_PI))
940                     + abs(r.width()*t.scalex * sin(t.rotate/180*M_PI)) );*/
941
942         value_w->setValue(i->sceneBoundingRect().width());
943         value_h->setValue(i->sceneBoundingRect().height());
944     } else if (i->type() == RECTITEM) {
945         QGraphicsRectItem *r = static_cast <QGraphicsRectItem *>(i);
946         value_w->setValue((int) r->rect().width());
947         value_h->setValue((int) r->rect().height());
948     } else if (i->type() == TEXTITEM) {
949         QGraphicsTextItem *t = static_cast <QGraphicsTextItem *>(i);
950         value_w->setValue((int) t->boundingRect().width());
951         value_h->setValue((int) t->boundingRect().height());
952     }
953
954     value_w->blockSignals(false);
955     value_h->blockSignals(false);
956 }
957
958 /** \brief Updates the coordinates in the text fields from the item */
959 void TitleWidget::updateCoordinates(QGraphicsItem *i)
960 {
961     // Block signals emitted by this method
962     value_x->blockSignals(true);
963     value_y->blockSignals(true);
964
965     if (i->type() == TEXTITEM) {
966
967         QGraphicsTextItem *rec = static_cast <QGraphicsTextItem *>(i);
968
969         // Set the correct x coordinate value
970         if (origin_x_left->isChecked()) {
971             // Origin (0 point) is at m_frameWidth, coordinate axis is inverted
972             value_x->setValue((int)(m_frameWidth - rec->pos().x() - rec->boundingRect().width()));
973         } else {
974             // Origin is at 0 (default)
975             value_x->setValue((int) rec->pos().x());
976         }
977
978         // Same for y
979         if (origin_y_top->isChecked()) {
980             value_y->setValue((int)(m_frameHeight - rec->pos().y() - rec->boundingRect().height()));
981         } else {
982             value_y->setValue((int) rec->pos().y());
983         }
984
985     } else if (i->type() == RECTITEM) {
986
987         QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(i);
988
989         if (origin_x_left->isChecked()) {
990             // Origin (0 point) is at m_frameWidth
991             value_x->setValue((int)(m_frameWidth - rec->pos().x() - rec->rect().width()));
992         } else {
993             // Origin is at 0 (default)
994             value_x->setValue((int) rec->pos().x());
995         }
996
997         if (origin_y_top->isChecked()) {
998             value_y->setValue((int)(m_frameHeight - rec->pos().y() - rec->rect().height()));
999         } else {
1000             value_y->setValue((int) rec->pos().y());
1001         }
1002
1003     } else if (i->type() == IMAGEITEM) {
1004
1005         if (origin_x_left->isChecked()) {
1006             value_x->setValue((int)(m_frameWidth - i->pos().x() - i->sceneBoundingRect().width()));
1007         } else {
1008             value_x->setValue((int) i->pos().x());
1009         }
1010
1011         if (origin_y_top->isChecked()) {
1012             value_y->setValue((int)(m_frameHeight - i->pos().y() - i->sceneBoundingRect().height()));
1013         } else {
1014             value_y->setValue((int) i->pos().y());
1015         }
1016
1017     }
1018
1019     // Stop blocking signals now
1020     value_x->blockSignals(false);
1021     value_y->blockSignals(false);
1022 }
1023
1024 void TitleWidget::updateRotZoom(QGraphicsItem *i)
1025 {
1026     itemzoom->blockSignals(true);
1027     itemrotate->blockSignals(false);
1028
1029     Transform t = m_transformations.value(i);
1030     itemzoom->setValue((int)(t.scalex * 100.0 + 0.5));
1031     itemrotate->setValue((int)(t.rotate));
1032
1033     itemzoom->blockSignals(false);
1034     itemrotate->blockSignals(false);
1035 }
1036
1037 /** \brief Updates the position of an item by reading coordinates from the text fields */
1038 void TitleWidget::updatePosition(QGraphicsItem *i)
1039 {
1040     if (i->type() == TEXTITEM) {
1041         QGraphicsTextItem *rec = static_cast <QGraphicsTextItem *>(i);
1042
1043         int posX;
1044         if (origin_x_left->isChecked()) {
1045             /* Origin of the x axis is at m_frameWidth,
1046              * and distance from right border of the item to the right
1047              * border of the frame is taken.
1048              * See comment to slotOriginXClicked().
1049              */
1050             posX = m_frameWidth - value_x->value() - rec->boundingRect().width();
1051         } else {
1052             posX = value_x->value();
1053         }
1054
1055         int posY;
1056         if (origin_y_top->isChecked()) {
1057             /* Same for y axis */
1058             posY = m_frameHeight - value_y->value() - rec->boundingRect().height();
1059         } else {
1060             posY = value_y->value();
1061         }
1062
1063         rec->setPos(posX, posY);
1064
1065     } else if (i->type() == RECTITEM) {
1066
1067         QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(i);
1068
1069         int posX;
1070         if (origin_x_left->isChecked()) {
1071             posX = m_frameWidth - value_x->value() - rec->rect().width();
1072         } else {
1073             posX = value_x->value();
1074         }
1075
1076         int posY;
1077         if (origin_y_top->isChecked()) {
1078             posY = m_frameHeight - value_y->value() - rec->rect().height();
1079         } else {
1080             posY = value_y->value();
1081         }
1082
1083         rec->setPos(posX, posY);
1084
1085     } else if (i->type() == IMAGEITEM) {
1086         int posX;
1087         if (origin_x_left->isChecked()) {
1088             // Use the sceneBoundingRect because this also regards transformations like zoom
1089             posX = m_frameWidth - value_x->value() - i->sceneBoundingRect().width();
1090         } else {
1091             posX = value_x->value();
1092         }
1093
1094         int posY;
1095         if (origin_y_top->isChecked()) {
1096             posY = m_frameHeight - value_y->value() - i->sceneBoundingRect().height();
1097         } else {
1098             posY = value_y->value();
1099         }
1100
1101         i->setPos(posX, posY);
1102
1103     }
1104
1105 }
1106
1107 void TitleWidget::updateTextOriginX()
1108 {
1109     if (origin_x_left->isChecked()) {
1110         origin_x_left->setText(i18n("\u2212X"));
1111     } else {
1112         origin_x_left->setText(i18n("+X"));
1113     }
1114 }
1115
1116 void TitleWidget::slotOriginXClicked()
1117 {
1118     // Update the text displayed on the button.
1119     updateTextOriginX();
1120
1121     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1122     if (l.size() >= 1) {
1123         updateCoordinates(l.at(0));
1124
1125         // Remember x axis setting
1126         l.at(0)->setData(TitleDocument::OriginXLeft, origin_x_left->isChecked() ?
1127                          TitleDocument::AxisInverted : TitleDocument::AxisDefault);
1128     }
1129     graphicsView->setFocus();
1130 }
1131
1132 void TitleWidget::updateTextOriginY()
1133 {
1134     if (origin_y_top->isChecked()) {
1135         origin_y_top->setText(i18n("\u2212Y"));
1136     } else {
1137         origin_y_top->setText(i18n("+Y"));
1138     }
1139 }
1140
1141 void TitleWidget::slotOriginYClicked()
1142 {
1143     // Update the text displayed on the button.
1144     updateTextOriginY();
1145
1146     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1147     if (l.size() >= 1) {
1148         updateCoordinates(l.at(0));
1149
1150         l.at(0)->setData(TitleDocument::OriginYTop, origin_y_top->isChecked() ?
1151                          TitleDocument::AxisInverted : TitleDocument::AxisDefault);
1152
1153     }
1154     graphicsView->setFocus();
1155 }
1156
1157 void TitleWidget::updateAxisButtons(QGraphicsItem *i)
1158 {
1159     int xAxis = i->data(TitleDocument::OriginXLeft).toInt();
1160     int yAxis = i->data(TitleDocument::OriginYTop).toInt();
1161     origin_x_left->blockSignals(true);
1162     origin_y_top->blockSignals(true);
1163
1164     if (xAxis == TitleDocument::AxisInverted) {
1165         origin_x_left->setChecked(true);
1166     } else {
1167         origin_x_left->setChecked(false);
1168     }
1169     updateTextOriginX();
1170
1171     if (yAxis == TitleDocument::AxisInverted) {
1172         origin_y_top->setChecked(true);
1173     } else {
1174         origin_y_top->setChecked(false);
1175     }
1176     updateTextOriginY();
1177
1178     origin_x_left->blockSignals(false);
1179     origin_y_top->blockSignals(false);
1180 }
1181
1182 void TitleWidget::slotChangeBackground()
1183 {
1184     QColor color = kcolorbutton->color();
1185     color.setAlpha(horizontalSlider->value());
1186     m_frameBorder->setBrush(QBrush(color));
1187 }
1188
1189 /**
1190  * Something (yeah) has changed in our QGraphicsScene.
1191  */
1192 void TitleWidget::slotChanged()
1193 {
1194     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1195     if (l.size() >= 1 && l.at(0)->type() == TEXTITEM) {
1196         textChanged(static_cast <QGraphicsTextItem *>(l.at(0)));
1197     }
1198 }
1199
1200 /**
1201  * If the user has set origin_x_left (everything also for y),
1202  * we need to look whether a text element has been selected. If yes,
1203  * we need to ensure that the right border of the text field
1204  * remains fixed also when some text has been entered.
1205  *
1206  * This is also known as right-justified, with the difference that
1207  * it is not valid for text but for its boundingRect. Text may still
1208  * be left-justified.
1209  */
1210 void TitleWidget::textChanged(QGraphicsTextItem *i)
1211 {
1212
1213     updateDimension(i);
1214
1215     if (origin_x_left->isChecked() || origin_y_top->isChecked()) {
1216
1217         if (!i->toPlainText().isEmpty()) {
1218             updatePosition(i);
1219         } else {
1220             /*
1221              * Don't do anything if the string is empty. If the position
1222              * would be updated here, a newly created text field would
1223              * be set to the position of the last selected text field.
1224              */
1225         }
1226     }
1227 }
1228
1229 void TitleWidget::slotInsertUnicode()
1230 {
1231     m_unicodeDialog->exec();
1232 }
1233
1234 void TitleWidget::slotInsertUnicodeString(QString text)
1235 {
1236     QList<QGraphicsItem *> l = graphicsView->scene()->selectedItems();
1237     if (l.size() > 0) {
1238         if (l.at(0)->type() == TEXTITEM) {
1239             QGraphicsTextItem *t = static_cast <QGraphicsTextItem *>(l.at(0));
1240             t->textCursor().insertText(text);
1241         }
1242     }
1243 }
1244
1245 void TitleWidget::slotUpdateText()
1246 {
1247     QFont font = font_family->currentFont();
1248     font.setPixelSize(font_size->value());
1249     font.setItalic(buttonItalic->isChecked());
1250     font.setUnderline(buttonUnder->isChecked());
1251     font.setWeight(font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
1252     QColor color = fontColorButton->color();
1253     color.setAlpha(textAlpha->value());
1254
1255     QGraphicsTextItem* item = NULL;
1256     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1257     if (l.size() == 1 && l.at(0)->type() == TEXTITEM) {
1258         item = static_cast <QGraphicsTextItem *>(l.at(0));
1259     }
1260     if (!item) return;
1261     //if (item->textCursor().selection ().isEmpty())
1262     QTextCursor cur = item->textCursor();
1263     QTextBlockFormat format = cur.blockFormat();
1264     if (buttonAlignLeft->isChecked() || buttonAlignCenter->isChecked() || buttonAlignRight->isChecked()) {
1265         item->setTextWidth(item->boundingRect().width());
1266         if (buttonAlignCenter->isChecked()) format.setAlignment(Qt::AlignHCenter);
1267         else if (buttonAlignRight->isChecked()) format.setAlignment(Qt::AlignRight);
1268         else if (buttonAlignLeft->isChecked()) format.setAlignment(Qt::AlignLeft);
1269     } else {
1270         format.setAlignment(Qt::AlignLeft);
1271         item->setTextWidth(-1);
1272     }
1273
1274     {
1275         item->setFont(font);
1276         item->setDefaultTextColor(color);
1277         cur.select(QTextCursor::Document);
1278         cur.setBlockFormat(format);
1279         item->setTextCursor(cur);
1280         cur.clearSelection();
1281         item->setTextCursor(cur);
1282
1283     }
1284 }
1285
1286 void TitleWidget::rectChanged()
1287 {
1288     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1289     if (l.size() == 1 && l.at(0)->type() == RECTITEM && !settingUp) {
1290         QGraphicsRectItem *rec = static_cast<QGraphicsRectItem *>(l.at(0));
1291         QColor f = rectFColor->color();
1292         f.setAlpha(rectFAlpha->value());
1293         QPen penf(f);
1294         penf.setWidth(rectLineWidth->value());
1295         rec->setPen(penf);
1296         QColor b = rectBColor->color();
1297         b.setAlpha(rectBAlpha->value());
1298         rec->setBrush(QBrush(b));
1299     }
1300 }
1301
1302 void TitleWidget::itemScaled(int val)
1303 {
1304     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1305     if (l.size() == 1) {
1306         Transform x = m_transformations.value(l.at(0));
1307         x.scalex = (double)val / 100.0;
1308         x.scaley = (double)val / 100.0;
1309         QTransform qtrans;
1310         qtrans.scale(x.scalex, x.scaley);
1311         qtrans.rotate(x.rotate);
1312         l[0]->setTransform(qtrans);
1313         m_transformations[l.at(0)] = x;
1314         updateDimension(l.at(0));
1315     }
1316 }
1317
1318 void TitleWidget::itemRotate(int val)
1319 {
1320     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1321     if (l.size() == 1) {
1322         Transform x = m_transformations[l.at(0)];
1323         x.rotate = (double)val;
1324         QTransform qtrans;
1325         qtrans.scale(x.scalex, x.scaley);
1326         qtrans.rotate(x.rotate);
1327         l[0]->setTransform(qtrans);
1328         m_transformations[l.at(0)] = x;
1329         updateDimension(l.at(0));
1330     }
1331 }
1332
1333 void TitleWidget::itemHCenter()
1334 {
1335     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1336     if (l.size() == 1) {
1337         QGraphicsItem *item = l.at(0);
1338         QRectF br = item->sceneBoundingRect();
1339         int width = (int)br.width();
1340         int newPos = (int)((m_frameWidth - width) / 2);
1341         newPos += item->pos().x() - br.left(); // Check item transformation
1342         item->setPos(newPos, item->pos().y());
1343         updateCoordinates(item);
1344     }
1345 }
1346
1347 void TitleWidget::itemVCenter()
1348 {
1349     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1350     if (l.size() == 1) {
1351         QGraphicsItem *item = l.at(0);
1352         QRectF br = item->sceneBoundingRect();
1353         int height = (int)br.height();
1354         int newPos = (int)((m_frameHeight - height) / 2);
1355         newPos += item->pos().y() - br.top(); // Check item transformation
1356         item->setPos(item->pos().x(), newPos);
1357         updateCoordinates(item);
1358     }
1359 }
1360
1361 void TitleWidget::itemTop()
1362 {
1363     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1364     if (l.size() == 1) {
1365         QGraphicsItem *item = l.at(0);
1366         QRectF br = item->sceneBoundingRect();
1367         double diff;
1368         if (br.top() > 0) diff = -br.top();
1369         else diff = -br.bottom();
1370         item->moveBy(0, diff);
1371         updateCoordinates(item);
1372     }
1373 }
1374
1375 void TitleWidget::itemBottom()
1376 {
1377     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1378     if (l.size() == 1) {
1379         QGraphicsItem *item = l.at(0);
1380         QRectF br = item->sceneBoundingRect();
1381         double diff;
1382         if (br.bottom() > m_frameHeight) diff = m_frameHeight - br.top();
1383         else diff = m_frameHeight - br.bottom();
1384         item->moveBy(0, diff);
1385         updateCoordinates(item);
1386     }
1387 }
1388
1389 void TitleWidget::itemLeft()
1390 {
1391     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1392     if (l.size() == 1) {
1393         QGraphicsItem *item = l.at(0);
1394         QRectF br = item->sceneBoundingRect();
1395         double diff;
1396         if (br.left() > 0) diff = -br.left();
1397         else diff = -br.right();
1398         item->moveBy(diff, 0);
1399         updateCoordinates(item);
1400     }
1401 }
1402
1403 void TitleWidget::itemRight()
1404 {
1405     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1406     if (l.size() == 1) {
1407         QGraphicsItem *item = l.at(0);
1408         QRectF br = item->sceneBoundingRect();
1409         double diff;
1410         if (br.right() < m_frameWidth) diff = m_frameWidth - br.right();
1411         else diff = m_frameWidth - br.left();
1412         item->moveBy(diff, 0);
1413         updateCoordinates(item);
1414     }
1415 }
1416
1417 void TitleWidget::setupViewports()
1418 {
1419     //double aspect_ratio = 4.0 / 3.0;//read from project
1420     //better zoom centered, but render uses only the created rect, so no problem to change the zoom function
1421     /*QRectF sp(0, 0, startViewportSize->value() * m_frameWidth / 100.0 , startViewportSize->value()* m_frameHeight / 100.0);
1422     QRectF ep(0, 0, endViewportSize->value() * m_frameWidth / 100.0, endViewportSize->value() * m_frameHeight / 100.0);
1423     // use a polygon thiat uses 16:9 and 4:3 rects forpreview the size in all aspect ratios ?
1424     QPolygonF spoly(sp);
1425     QPolygonF epoly(ep);
1426     spoly.translate(startViewportX->value(), startViewportY->value());
1427     epoly.translate(endViewportX->value(), endViewportY->value());
1428     m_startViewport->setPolygon(spoly);
1429     m_endViewport->setPolygon(epoly);
1430     if (! insertingValues) {
1431         m_startViewport->setData(0, startViewportX->value());
1432         m_startViewport->setData(1, startViewportY->value());
1433         m_startViewport->setData(2, startViewportSize->value());
1434
1435         m_endViewport->setData(0, endViewportX->value());
1436         m_endViewport->setData(1, endViewportY->value());
1437         m_endViewport->setData(2, endViewportSize->value());
1438     }*/
1439 }
1440
1441 void TitleWidget::loadTitle(KUrl url)
1442 {
1443     if (url.isEmpty()) url = KFileDialog::getOpenUrl(KUrl(m_projectTitlePath), "application/x-kdenlivetitle", this, i18n("Load Title"));
1444     if (!url.isEmpty()) {
1445         QList<QGraphicsItem *> items = m_scene->items();
1446         for (int i = 0; i < items.size(); i++) {
1447             if (items.at(i)->zValue() > -1000) delete items.at(i);
1448         }
1449         m_scene->clearTextSelection();
1450         QDomDocument doc;
1451         QString tmpfile;
1452
1453         if (KIO::NetAccess::download(url, tmpfile, 0)) {
1454             QFile file(tmpfile);
1455             if (file.open(QIODevice::ReadOnly)) {
1456                 doc.setContent(&file, false);
1457                 file.close();
1458             } else return;
1459             KIO::NetAccess::removeTempFile(tmpfile);
1460         }
1461         setXml(doc);
1462
1463         /*int out;
1464         m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport, &out) + 1;
1465         adjustFrameSize();
1466         title_duration->setText(m_tc.getTimecode(GenTime(out, m_render->fps())));
1467         insertingValues = true;
1468         startViewportX->setValue(m_startViewport->data(0).toInt());
1469         startViewportY->setValue(m_startViewport->data(1).toInt());
1470         startViewportSize->setValue(m_startViewport->data(2).toInt());
1471         endViewportX->setValue(m_endViewport->data(0).toInt());
1472         endViewportY->setValue(m_endViewport->data(1).toInt());
1473         endViewportSize->setValue(m_endViewport->data(2).toInt());
1474
1475         insertingValues = false;
1476         slotSelectTool();
1477         slotAdjustZoom();*/
1478     }
1479 }
1480
1481 void TitleWidget::saveTitle(KUrl url)
1482 {
1483     if (anim_start->isChecked()) slotAnimStart(false);
1484     if (anim_end->isChecked()) slotAnimEnd(false);
1485     if (url.isEmpty()) {
1486         KFileDialog *fs = new KFileDialog(KUrl(m_projectTitlePath), "application/x-kdenlivetitle", this);
1487         fs->setOperationMode(KFileDialog::Saving);
1488         fs->setMode(KFile::File);
1489 #if KDE_IS_VERSION(4,2,0)
1490         fs->setConfirmOverwrite(true);
1491 #endif
1492         fs->setKeepLocation(true);
1493         fs->exec();
1494         url = fs->selectedUrl();
1495         delete fs;
1496     }
1497     if (!url.isEmpty()) {
1498         if (m_titledocument.saveDocument(url, m_startViewport, m_endViewport, m_tc.getFrameCount(title_duration->text())) == false)
1499             KMessageBox::error(this, i18n("Cannot write to file %1", url.path()));
1500     }
1501 }
1502
1503 QDomDocument TitleWidget::xml()
1504 {
1505     QDomDocument doc = m_titledocument.xml(m_startViewport, m_endViewport);
1506     doc.documentElement().setAttribute("out", m_tc.getFrameCount(title_duration->text()));
1507     return doc;
1508 }
1509
1510 int TitleWidget::duration() const
1511 {
1512     return m_tc.getFrameCount(title_duration->text());
1513 }
1514
1515 void TitleWidget::setXml(QDomDocument doc)
1516 {
1517     int out;
1518     m_count = m_titledocument.loadFromXml(doc, m_startViewport, m_endViewport, &out);
1519     adjustFrameSize();
1520     title_duration->setText(m_tc.getTimecode(GenTime(out, m_render->fps())));
1521     /*if (doc.documentElement().hasAttribute("out")) {
1522     GenTime duration = GenTime(doc.documentElement().attribute("out").toDouble() / 1000.0);
1523     title_duration->setText(m_tc.getTimecode(duration));
1524     }
1525     else title_duration->setText(m_tc.getTimecode(GenTime(5000)));*/
1526
1527     QDomElement e = doc.documentElement();
1528     m_transformations.clear();
1529     QList <QGraphicsItem *> items = graphicsView->scene()->items();
1530     const double PI = 4.0 * atan(1.0);
1531     for (int i = 0; i < items.count(); i++) {
1532         QTransform t = items.at(i)->transform();
1533         Transform x;
1534         x.scalex = t.m11();
1535         x.scaley = t.m22();
1536         x.rotate = 180. / PI * atan2(-t.m21(), t.m11());
1537         m_transformations[items.at(i)] = x;
1538     }
1539     // mbd: Update the GUI color selectors to match the stuff from the loaded document
1540     QColor background_color = m_titledocument.getBackgroundColor();
1541     horizontalSlider->blockSignals(true);
1542     kcolorbutton->blockSignals(true);
1543     horizontalSlider->setValue(background_color.alpha());
1544     background_color.setAlpha(255);
1545     kcolorbutton->setColor(background_color);
1546     horizontalSlider->blockSignals(false);
1547     kcolorbutton->blockSignals(false);
1548
1549     /*startViewportX->setValue(m_startViewport->data(0).toInt());
1550     startViewportY->setValue(m_startViewport->data(1).toInt());
1551     startViewportSize->setValue(m_startViewport->data(2).toInt());
1552     endViewportX->setValue(m_endViewport->data(0).toInt());
1553     endViewportY->setValue(m_endViewport->data(1).toInt());
1554     endViewportSize->setValue(m_endViewport->data(2).toInt());*/
1555
1556     QTimer::singleShot(200, this, SLOT(slotAdjustZoom()));
1557     slotSelectTool();
1558 }
1559
1560 /** \brief Connected to the accepted signal - calls writeChoices */
1561 void TitleWidget::slotAccepted()
1562 {
1563     if (anim_start->isChecked()) slotAnimStart(false);
1564     if (anim_end->isChecked()) slotAnimEnd(false);
1565     writeChoices();
1566 }
1567
1568 /** \brief Store the current choices of font, background and rect values */
1569 void TitleWidget::writeChoices()
1570 {
1571     // Get a pointer to a shared configuration instance, then get the TitleWidget group.
1572     KSharedConfigPtr config = KGlobal::config();
1573     KConfigGroup titleConfig(config, "TitleWidget");
1574     // Write the entries
1575     titleConfig.writeEntry("font_family", font_family->currentFont());
1576     //titleConfig.writeEntry("font_size", font_size->value());
1577     titleConfig.writeEntry("font_pixel_size", font_size->value());
1578     titleConfig.writeEntry("font_color", fontColorButton->color());
1579     titleConfig.writeEntry("font_alpha", textAlpha->value());
1580     titleConfig.writeEntry("font_weight", font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
1581     titleConfig.writeEntry("font_italic", buttonItalic->isChecked());
1582     titleConfig.writeEntry("font_underlined", buttonUnder->isChecked());
1583
1584     titleConfig.writeEntry("rect_foreground_color", rectFColor->color());
1585     titleConfig.writeEntry("rect_foreground_alpha", rectFAlpha->value());
1586     titleConfig.writeEntry("rect_background_color", rectBColor->color());
1587     titleConfig.writeEntry("rect_background_alpha", rectBAlpha->value());
1588     titleConfig.writeEntry("rect_line_width", rectLineWidth->value());
1589
1590     titleConfig.writeEntry("background_color", kcolorbutton->color());
1591     titleConfig.writeEntry("background_alpha", horizontalSlider->value());
1592
1593     //! \todo Not sure if I should sync - it is probably safe to do it
1594     config->sync();
1595
1596 }
1597
1598 /** \brief Read the last stored choices into the dialog */
1599 void TitleWidget::readChoices()
1600 {
1601     // Get a pointer to a shared configuration instance, then get the TitleWidget group.
1602     KSharedConfigPtr config = KGlobal::config();
1603     KConfigGroup titleConfig(config, "TitleWidget");
1604     // read the entries
1605     font_family->setCurrentFont(titleConfig.readEntry("font_family", font_family->currentFont()));
1606     font_size->setValue(titleConfig.readEntry("font_pixel_size", font_size->value()));
1607     fontColorButton->setColor(titleConfig.readEntry("font_color", fontColorButton->color()));
1608     textAlpha->setValue(titleConfig.readEntry("font_alpha", textAlpha->value()));
1609     int weight;
1610     if (titleConfig.readEntry("font_bold", false)) weight = QFont::Bold;
1611     else weight = titleConfig.readEntry("font_weight", font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
1612     setFontBoxWeight(weight);
1613     buttonItalic->setChecked(titleConfig.readEntry("font_italic", buttonItalic->isChecked()));
1614     buttonUnder->setChecked(titleConfig.readEntry("font_underlined", buttonUnder->isChecked()));
1615
1616     rectFColor->setColor(titleConfig.readEntry("rect_foreground_color", rectFColor->color()));
1617     rectFAlpha->setValue(titleConfig.readEntry("rect_foreground_alpha", rectFAlpha->value()));
1618     rectBColor->setColor(titleConfig.readEntry("rect_background_color", rectBColor->color()));
1619     rectBAlpha->setValue(titleConfig.readEntry("rect_background_alpha", rectBAlpha->value()));
1620     rectLineWidth->setValue(titleConfig.readEntry("rect_line_width", rectLineWidth->value()));
1621
1622     kcolorbutton->setColor(titleConfig.readEntry("background_color", kcolorbutton->color()));
1623     horizontalSlider->setValue(titleConfig.readEntry("background_alpha", horizontalSlider->value()));
1624 }
1625
1626 void TitleWidget::adjustFrameSize()
1627 {
1628     m_frameWidth = m_titledocument.frameWidth();
1629     m_frameHeight = m_titledocument.frameHeight();
1630     m_frameBorder->setRect(0, 0, m_frameWidth, m_frameHeight);
1631     displayBackgroundFrame();
1632 }
1633
1634 void TitleWidget::slotAnimStart(bool anim)
1635 {
1636     if (anim && anim_end->isChecked()) {
1637         anim_end->setChecked(false);
1638         m_endViewport->setZValue(-1000);
1639         m_endViewport->setBrush(QBrush());
1640     }
1641     slotSelectTool();
1642     QList<QGraphicsItem *> list = m_scene->items();
1643     for (int i = 0; i < list.count(); i++) {
1644         if (list.at(i)->zValue() > -1000) {
1645             list.at(i)->setFlag(QGraphicsItem::ItemIsMovable, !anim);
1646             list.at(i)->setFlag(QGraphicsItem::ItemIsSelectable, !anim);
1647         }
1648     }
1649     align_box->setEnabled(anim);
1650     itemzoom->setEnabled(!anim);
1651     itemrotate->setEnabled(!anim);
1652     frame_toolbar->setEnabled(!anim);
1653     rect_properties->setEnabled(!anim);
1654     if (anim) {
1655         keep_aspect->setChecked(!m_startViewport->data(0).isNull());
1656         m_startViewport->setZValue(1100);
1657         QColor col = m_startViewport->pen().color();
1658         col.setAlpha(100);
1659         m_startViewport->setBrush(col);
1660         m_startViewport->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
1661         m_startViewport->setSelected(true);
1662         selectionChanged();
1663         slotSelectTool();
1664         if (m_startViewport->childItems().isEmpty()) addAnimInfoText();
1665     } else {
1666         m_startViewport->setZValue(-1000);
1667         m_startViewport->setBrush(QBrush());
1668         m_startViewport->setFlags(0);
1669         if (!anim_end->isChecked()) deleteAnimInfoText();
1670     }
1671
1672 }
1673
1674 void TitleWidget::slotAnimEnd(bool anim)
1675 {
1676     if (anim && anim_start->isChecked()) {
1677         anim_start->setChecked(false);
1678         m_startViewport->setZValue(-1000);
1679         m_startViewport->setBrush(QBrush());
1680     }
1681     slotSelectTool();
1682     QList<QGraphicsItem *> list = m_scene->items();
1683     for (int i = 0; i < list.count(); i++) {
1684         if (list.at(i)->zValue() > -1000) {
1685             list.at(i)->setFlag(QGraphicsItem::ItemIsMovable, !anim);
1686             list.at(i)->setFlag(QGraphicsItem::ItemIsSelectable, !anim);
1687         }
1688     }
1689     align_box->setEnabled(anim);
1690     itemzoom->setEnabled(!anim);
1691     itemrotate->setEnabled(!anim);
1692     frame_toolbar->setEnabled(!anim);
1693     rect_properties->setEnabled(!anim);
1694     if (anim) {
1695         keep_aspect->setChecked(!m_endViewport->data(0).isNull());
1696         m_endViewport->setZValue(1100);
1697         QColor col = m_endViewport->pen().color();
1698         col.setAlpha(100);
1699         m_endViewport->setBrush(col);
1700         m_endViewport->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
1701         m_endViewport->setSelected(true);
1702         selectionChanged();
1703         slotSelectTool();
1704         if (m_endViewport->childItems().isEmpty()) addAnimInfoText();
1705     } else {
1706         m_endViewport->setZValue(-1000);
1707         m_endViewport->setBrush(QBrush());
1708         m_endViewport->setFlags(0);
1709         if (!anim_start->isChecked()) deleteAnimInfoText();
1710     }
1711 }
1712
1713 void TitleWidget::addAnimInfoText()
1714 {
1715     // add text to anim viewport
1716     QGraphicsTextItem *t = new QGraphicsTextItem(i18n("Start"), m_startViewport);
1717     QGraphicsTextItem *t2 = new QGraphicsTextItem(i18n("End"), m_endViewport);
1718     QFont font = t->font();
1719     font.setPixelSize(m_startViewport->rect().width() / 10);
1720     QColor col = m_startViewport->pen().color();
1721     col.setAlpha(255);
1722     t->setDefaultTextColor(col);
1723     t->setFont(font);
1724     font.setPixelSize(m_endViewport->rect().width() / 10);
1725     col = m_endViewport->pen().color();
1726     col.setAlpha(255);
1727     t2->setDefaultTextColor(col);
1728     t2->setFont(font);
1729 }
1730
1731 void TitleWidget::updateInfoText()
1732 {
1733     // update info text font
1734     if (!m_startViewport->childItems().isEmpty()) {
1735         QGraphicsTextItem *item = static_cast <QGraphicsTextItem *>(m_startViewport->childItems().at(0));
1736         if (item) {
1737             QFont font = item->font();
1738             font.setPixelSize(m_startViewport->rect().width() / 10);
1739             item->setFont(font);
1740         }
1741     }
1742     if (!m_endViewport->childItems().isEmpty()) {
1743         QGraphicsTextItem *item = static_cast <QGraphicsTextItem *>(m_endViewport->childItems().at(0));
1744         if (item) {
1745             QFont font = item->font();
1746             font.setPixelSize(m_endViewport->rect().width() / 10);
1747             item->setFont(font);
1748         }
1749     }
1750 }
1751
1752 void TitleWidget::deleteAnimInfoText()
1753 {
1754     // end animation editing, remove info text
1755     while (!m_startViewport->childItems().isEmpty()) {
1756         QGraphicsItem *item = m_startViewport->childItems().at(0);
1757         m_scene->removeItem(item);
1758         delete item;
1759     }
1760     while (!m_endViewport->childItems().isEmpty()) {
1761         QGraphicsItem *item = m_endViewport->childItems().at(0);
1762         m_scene->removeItem(item);
1763         delete item;
1764     }
1765 }
1766
1767
1768 void TitleWidget::slotKeepAspect(bool keep)
1769 {
1770     if (m_endViewport->zValue() == 1100) {
1771         m_endViewport->setData(0, keep == true ? m_frameWidth : QVariant());
1772         m_endViewport->setData(1, keep == true ? m_frameHeight : QVariant());
1773     } else {
1774         m_startViewport->setData(0, keep == true ? m_frameWidth : QVariant());
1775         m_startViewport->setData(1, keep == true ? m_frameHeight : QVariant());
1776     }
1777 }
1778
1779 void TitleWidget::slotResize50()
1780 {
1781     if (m_endViewport->zValue() == 1100) {
1782         m_endViewport->setRect(0, 0, m_frameWidth / 2, m_frameHeight / 2);
1783     } else m_startViewport->setRect(0, 0, m_frameWidth / 2, m_frameHeight / 2);
1784 }
1785
1786 void TitleWidget::slotResize100()
1787 {
1788     if (m_endViewport->zValue() == 1100) {
1789         m_endViewport->setRect(0, 0, m_frameWidth, m_frameHeight);
1790     } else m_startViewport->setRect(0, 0, m_frameWidth, m_frameHeight);
1791 }
1792
1793 void TitleWidget::slotResize200()
1794 {
1795     if (m_endViewport->zValue() == 1100) {
1796         m_endViewport->setRect(0, 0, m_frameWidth * 2, m_frameHeight * 2);
1797     } else m_startViewport->setRect(0, 0, m_frameWidth * 2, m_frameHeight * 2);
1798 }
1799
1800 void TitleWidget::slotAddEffect(int ix)
1801 {
1802 #if QT_VERSION < 0x040600
1803     return;
1804 #else
1805     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1806     QGraphicsEffect *eff = NULL;
1807     if (ix == 1) {
1808         // Blur effect
1809         eff = new QGraphicsBlurEffect();
1810         shadow_frame->setHidden(true);
1811         blur_frame->setHidden(false);
1812     } else if (ix == 2) {
1813         eff = new QGraphicsDropShadowEffect();
1814         blur_frame->setHidden(true);
1815         shadow_frame->setHidden(false);
1816     } else {
1817         blur_frame->setHidden(true);
1818         shadow_frame->setHidden(true);
1819     }
1820     if (l.size() == 1) {
1821         l[0]->setGraphicsEffect(eff);
1822     } else delete eff;
1823 #endif
1824 }
1825
1826
1827 void TitleWidget::slotFontText(const QString& s)
1828 {
1829     const QFont f(s);
1830     if (f.exactMatch()) {
1831         // Font really exists (could also just be a «d» if the user
1832         // starts typing «dejavu» for example).
1833         font_family->setCurrentFont(f);
1834     }
1835     // TODO: typing dejavu serif does not recognize the font (takes sans).
1836     // upper/lowercase problem?
1837 }
1838
1839 void TitleWidget::slotEditBlur(int ix)
1840 {
1841 #if QT_VERSION < 0x040600
1842     return;
1843 #else
1844     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1845     if (l.size() == 1) {
1846         QGraphicsEffect *eff = l[0]->graphicsEffect();
1847         QGraphicsBlurEffect *blur = static_cast <QGraphicsBlurEffect *>(eff);
1848         if (blur) blur->setBlurRadius(ix);
1849     }
1850 #endif
1851 }
1852
1853 void TitleWidget::slotEditShadow()
1854 {
1855 #if QT_VERSION < 0x040600
1856     return;
1857 #else
1858     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1859     if (l.size() == 1) {
1860         QGraphicsEffect *eff = l[0]->graphicsEffect();
1861         QGraphicsDropShadowEffect *shadow = static_cast <QGraphicsDropShadowEffect *>(eff);
1862         if (shadow) {
1863             shadow->setBlurRadius(shadow_radius->value());
1864             shadow->setOffset(shadow_x->value(), shadow_y->value());
1865         }
1866     }
1867 #endif
1868 }