]> git.sesse.net Git - kdenlive/blob - src/titlewidget.cpp
Update for new titler module, turn clip speed into an effect, mem leaks and more
[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
29 #include <QDomDocument>
30 #include <QGraphicsItem>
31 #include <QGraphicsSvgItem>
32 #include <QTimer>
33 #include <QToolBar>
34 #include <QMenu>
35 #include <QSignalMapper>
36 #include <QTextBlockFormat>
37 #include <QTextCursor>
38
39 int settingUp = false;
40
41 const int IMAGEITEM = 7;
42 const int RECTITEM = 3;
43 const int TEXTITEM = 8;
44 static bool insertingValues = false;
45
46 TitleWidget::TitleWidget(KUrl url, Timecode tc, QString projectTitlePath, Render *render, QWidget *parent) :
47         QDialog(parent),
48         Ui::TitleWidget_UI(),
49         m_startViewport(NULL),
50         m_endViewport(NULL),
51         m_render(render),
52         m_count(0),
53         m_unicodeDialog(new UnicodeDialog(UnicodeDialog::InputHex)),
54         m_projectTitlePath(projectTitlePath),
55         m_tc(tc)
56 {
57     setupUi(this);
58     setFont(KGlobalSettings::toolBarFont());
59     //toolBox->setFont(KGlobalSettings::toolBarFont());
60     frame_properties->setEnabled(false);
61     rect_properties->setFixedHeight(frame_properties->height() + 4);
62     no_properties->setFixedHeight(frame_properties->height() + 4);
63     image_properties->setFixedHeight(frame_properties->height() + 4);
64     text_properties->setFixedHeight(frame_properties->height() + 4);
65     frame_properties->setFixedHeight(frame_toolbar->height());
66     m_frameWidth = render->renderWidth();
67     m_frameHeight = render->renderHeight();
68     showToolbars(TITLE_NONE);
69
70     //TODO: get default title duration instead of hardcoded one
71     title_duration->setText(m_tc.getTimecode(GenTime(5000 / 1000.0), m_render->fps()));
72
73     connect(kcolorbutton, SIGNAL(clicked()), this, SLOT(slotChangeBackground())) ;
74     connect(horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChangeBackground())) ;
75
76     connect(fontColorButton, SIGNAL(clicked()), this, SLOT(slotUpdateText())) ;
77     connect(font_family, SIGNAL(currentFontChanged(const QFont &)), this, SLOT(slotUpdateText())) ;
78     connect(font_size, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText())) ;
79     connect(textAlpha, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText()));
80     connect(font_weight_box, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateText()));
81
82     connect(rectFAlpha, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
83     connect(rectBAlpha, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
84     connect(rectFColor, SIGNAL(clicked()), this, SLOT(rectChanged()));
85     connect(rectBColor, SIGNAL(clicked()), this, SLOT(rectChanged()));
86     connect(rectLineWidth, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
87
88     connect(startViewportX, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
89     connect(startViewportY, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
90     connect(startViewportSize, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
91     connect(endViewportX, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
92     connect(endViewportY, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
93     connect(endViewportSize, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
94
95     connect(zValue, SIGNAL(valueChanged(int)), this, SLOT(zIndexChanged(int)));
96     connect(itemzoom, SIGNAL(valueChanged(int)), this, SLOT(itemScaled(int)));
97     connect(itemrotate, SIGNAL(valueChanged(int)), this, SLOT(itemRotate(int)));
98     connect(itemhcenter, SIGNAL(clicked()), this, SLOT(itemHCenter()));
99     connect(itemvcenter, SIGNAL(clicked()), this, SLOT(itemVCenter()));
100
101     connect(origin_x_left, SIGNAL(clicked()), this, SLOT(slotOriginXClicked()));
102     connect(origin_y_top, SIGNAL(clicked()), this, SLOT(slotOriginYClicked()));
103
104     m_signalMapper = new QSignalMapper(this);
105     m_signalMapper->setMapping(value_w, ValueWidth);
106     m_signalMapper->setMapping(value_h, ValueHeight);
107     connect(value_w, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
108     connect(value_h, SIGNAL(valueChanged(int)), m_signalMapper, SLOT(map()));
109     connect(m_signalMapper, SIGNAL(mapped(int)), this, SLOT(slotValueChanged(int)));
110
111     connect(value_x, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
112     connect(value_y, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
113     connect(value_w, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
114     connect(value_h, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
115     connect(buttonFitZoom, SIGNAL(clicked()), this, SLOT(slotAdjustZoom()));
116     connect(buttonRealSize, SIGNAL(clicked()), this, SLOT(slotZoomOneToOne()));
117     connect(buttonItalic, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
118     connect(buttonUnder, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
119     connect(buttonAlignLeft, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
120     connect(buttonAlignRight, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
121     connect(buttonAlignCenter, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
122     connect(buttonAlignNone, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
123     //connect(buttonInsertUnicode, SIGNAL(clicked()), this, SLOT(slotInsertUnicode()));
124     connect(displayBg, SIGNAL(stateChanged(int)), this, SLOT(displayBackgroundFrame()));
125
126     connect(m_unicodeDialog, SIGNAL(charSelected(QString)), this, SLOT(slotInsertUnicodeString(QString)));
127
128     // mbd
129     connect(this, SIGNAL(accepted()), this, SLOT(slotAccepted()));
130
131     font_weight_box->blockSignals(true);
132     font_weight_box->addItem(i18nc("Font style", "Light"), QFont::Light);
133     font_weight_box->addItem(i18nc("Font style", "Normal"), QFont::Normal);
134     font_weight_box->addItem(i18nc("Font style", "Demi-Bold"), QFont::DemiBold);
135     font_weight_box->addItem(i18nc("Font style", "Bold"), QFont::Bold);
136     font_weight_box->addItem(i18nc("Font style", "Black"), QFont::Black);
137     font_weight_box->setToolTip(i18n("Font weight"));
138     font_weight_box->setCurrentIndex(1);
139     font_weight_box->blockSignals(false);
140
141     buttonFitZoom->setIcon(KIcon("zoom-fit-best"));
142     buttonRealSize->setIcon(KIcon("zoom-original"));
143     buttonItalic->setIcon(KIcon("format-text-italic"));
144     buttonUnder->setIcon(KIcon("format-text-underline"));
145     buttonAlignCenter->setIcon(KIcon("format-justify-center"));
146     buttonAlignLeft->setIcon(KIcon("format-justify-left"));
147     buttonAlignRight->setIcon(KIcon("format-justify-right"));
148     buttonAlignNone->setIcon(KIcon("kdenlive-align-none"));
149
150     buttonAlignNone->setToolTip(i18n("No alignment"));
151     buttonAlignRight->setToolTip(i18n("Align right"));
152     buttonAlignLeft->setToolTip(i18n("Align left"));
153     buttonAlignCenter->setToolTip(i18n("Align center"));
154
155     m_unicodeAction = new QAction(KIcon("kdenlive-insert-unicode"), QString(), this);
156     m_unicodeAction->setShortcut(Qt::SHIFT + Qt::CTRL + Qt::Key_U);
157     m_unicodeAction->setToolTip(i18n("Insert Unicode character") + ' ' + m_unicodeAction->shortcut().toString());
158     connect(m_unicodeAction, SIGNAL(triggered()), this, SLOT(slotInsertUnicode()));
159     buttonInsertUnicode->setDefaultAction(m_unicodeAction);
160
161     origin_x_left->setToolTip(i18n("Invert x axis and change 0 point"));
162     origin_y_top->setToolTip(i18n("Invert y axis and change 0 point"));
163     rectBColor->setToolTip(i18n("Select fill color"));
164     rectFColor->setToolTip(i18n("Select border color"));
165     rectBAlpha->setToolTip(i18n("Fill transparency"));
166     rectFAlpha->setToolTip(i18n("Border transparency"));
167     zoom_slider->setToolTip(i18n("Zoom"));
168     buttonRealSize->setToolTip(i18n("Original size (1:1)"));
169     buttonFitZoom->setToolTip(i18n("Fit zoom"));
170     kcolorbutton->setToolTip(i18n("Select background color"));
171     horizontalSlider->setToolTip(i18n("Background Transparency"));
172
173     itemhcenter->setIcon(KIcon("kdenlive-align-hor"));
174     itemhcenter->setToolTip(i18n("Align item horizontally"));
175     itemvcenter->setIcon(KIcon("kdenlive-align-vert"));
176     itemvcenter->setToolTip(i18n("Align item vertically"));
177
178     QHBoxLayout *layout = new QHBoxLayout;
179     frame_toolbar->setLayout(layout);
180     layout->setContentsMargins(2, 2, 2, 2);
181     QToolBar *m_toolbar = new QToolBar("titleToolBar", this);
182
183     m_buttonCursor = m_toolbar->addAction(KIcon("transform-move"), QString());
184     m_buttonCursor->setCheckable(true);
185     m_buttonCursor->setShortcut(Qt::ALT + Qt::Key_S);
186     m_buttonCursor->setToolTip(i18n("Selection Tool") + ' ' + m_buttonCursor->shortcut().toString());
187     connect(m_buttonCursor, SIGNAL(triggered()), this, SLOT(slotSelectTool()));
188
189     m_buttonText = m_toolbar->addAction(KIcon("insert-text"), QString());
190     m_buttonText->setCheckable(true);
191     m_buttonText->setShortcut(Qt::ALT + Qt::Key_T);
192     m_buttonText->setToolTip(i18n("Add Text") + ' ' + m_buttonText->shortcut().toString());
193     connect(m_buttonText, SIGNAL(triggered()), this, SLOT(slotTextTool()));
194
195     m_buttonRect = m_toolbar->addAction(KIcon("kdenlive-insert-rect"), QString());
196     m_buttonRect->setCheckable(true);
197     m_buttonRect->setShortcut(Qt::ALT + Qt::Key_R);
198     m_buttonRect->setToolTip(i18n("Add Rectangle") + ' ' + m_buttonRect->shortcut().toString());
199     connect(m_buttonRect, SIGNAL(triggered()), this, SLOT(slotRectTool()));
200
201     m_buttonImage = m_toolbar->addAction(KIcon("insert-image"), QString());
202     m_buttonImage->setCheckable(false);
203     m_buttonImage->setShortcut(Qt::ALT + Qt::Key_I);
204     m_buttonImage->setToolTip(i18n("Add Image") + ' ' + m_buttonImage->shortcut().toString());
205     connect(m_buttonImage, SIGNAL(triggered()), this, SLOT(slotImageTool()));
206
207     m_toolbar->addSeparator();
208
209     m_buttonLoad = m_toolbar->addAction(KIcon("document-open"), i18n("Open Document"));
210     m_buttonLoad->setCheckable(false);
211     m_buttonLoad->setShortcut(Qt::CTRL + Qt::Key_O);
212     connect(m_buttonLoad, SIGNAL(triggered()), this, SLOT(loadTitle()));
213
214     m_buttonSave = m_toolbar->addAction(KIcon("document-save-as"), i18n("Save As"));
215     m_buttonSave->setCheckable(false);
216     m_buttonSave->setShortcut(Qt::CTRL + Qt::Key_S);
217     connect(m_buttonSave, SIGNAL(triggered()), this, SLOT(saveTitle()));
218
219     layout->addWidget(m_toolbar);
220
221     // initialize graphic scene
222     m_scene = new GraphicsSceneRectMove(this);
223     graphicsView->setScene(m_scene);
224     m_titledocument.setScene(m_scene);
225     connect(m_scene, SIGNAL(changed(QList<QRectF>)), this, SLOT(slotChanged()));
226
227     // a gradient background
228     /*QRadialGradient *gradient = new QRadialGradient(0, 0, 10);
229     gradient->setSpread(QGradient::ReflectSpread);
230     scene->setBackgroundBrush(*gradient);*/
231
232     m_frameImage = new QGraphicsPixmapItem();
233     QTransform qtrans;
234     qtrans.scale(2.0, 2.0);
235     m_frameImage->setTransform(qtrans);
236     m_frameImage->setZValue(-1200);
237     m_frameImage->setFlags(QGraphicsItem::ItemClipsToShape);
238     displayBackgroundFrame();
239     graphicsView->scene()->addItem(m_frameImage);
240
241     connect(m_scene, SIGNAL(selectionChanged()), this , SLOT(selectionChanged()));
242     connect(m_scene, SIGNAL(itemMoved()), this , SLOT(selectionChanged()));
243     connect(m_scene, SIGNAL(sceneZoom(bool)), this , SLOT(slotZoom(bool)));
244     connect(m_scene, SIGNAL(actionFinished()), this , SLOT(slotSelectTool()));
245     //connect(m_scene, SIGNAL(actionFinished()), this , SLOT(selectionChanged()));
246     connect(m_scene, SIGNAL(newRect(QGraphicsRectItem *)), this , SLOT(slotNewRect(QGraphicsRectItem *)));
247     connect(m_scene, SIGNAL(newText(QGraphicsTextItem *)), this , SLOT(slotNewText(QGraphicsTextItem *)));
248     connect(zoom_slider, SIGNAL(valueChanged(int)), this , SLOT(slotUpdateZoom(int)));
249
250     QPen framepen(Qt::DotLine);
251     framepen.setColor(Qt::red);
252
253     m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
254     m_frameBorder->setPen(framepen);
255     m_frameBorder->setZValue(-1100);
256     m_frameBorder->setBrush(Qt::transparent);
257     m_frameBorder->setFlags(QGraphicsItem::ItemClipsToShape);
258     graphicsView->scene()->addItem(m_frameBorder);
259
260     // mbd: load saved settings
261     readChoices();
262
263     initViewports();
264     QTimer::singleShot(500, this, SLOT(slotAdjustZoom()));
265     graphicsView->show();
266     //graphicsView->setRenderHint(QPainter::Antialiasing);
267     graphicsView->setInteractive(true);
268     //graphicsView->resize(400, 300);
269     kDebug() << "// TITLE WIDGWT: " << graphicsView->viewport()->width() << "x" << graphicsView->viewport()->height();
270     //toolBox->setItemEnabled(2, false);
271     if (!url.isEmpty()) {
272         double out;
273         m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport, &out) + 1;
274         title_duration->setText(m_tc.getTimecode(GenTime(out), m_render->fps()));
275         slotSelectTool();
276     } else {
277         slotTextTool();
278     }
279 }
280
281 TitleWidget::~TitleWidget()
282 {
283     delete m_buttonRect;
284     delete m_buttonText;
285     delete m_buttonImage;
286     delete m_buttonCursor;
287     delete m_buttonSave;
288     delete m_buttonLoad;
289     delete m_unicodeAction;
290
291     delete m_unicodeDialog;
292     delete m_frameBorder;
293     delete m_frameImage;
294     delete m_startViewport;
295     delete m_endViewport;
296     delete m_scene;
297     delete m_signalMapper;
298 }
299
300 //static
301 QStringList TitleWidget::getFreeTitleInfo(const KUrl &projectUrl, bool isClone)
302 {
303     QStringList result;
304     QString titlePath = projectUrl.path(KUrl::AddTrailingSlash) + "titles/";
305     KStandardDirs::makeDir(titlePath);
306     titlePath.append((isClone == false) ? "title" : "clone");
307     int counter = 0;
308     QString path;
309     while (path.isEmpty() || QFile::exists(path)) {
310         counter++;
311         path = titlePath + QString::number(counter).rightJustified(3, '0', false) + ".png";
312     }
313     result.append(((isClone == false) ? i18n("Title") : i18n("Clone")) + ' ' + QString::number(counter).rightJustified(3, '0', false));
314     result.append(path);
315     return result;
316 }
317
318 QString TitleWidget::getTitleResourceFromName(const KUrl &projectUrl, const QString &titleName)
319 {
320     QStringList result;
321     QString titlePath = projectUrl.path(KUrl::AddTrailingSlash) + "titles/";
322     KStandardDirs::makeDir(titlePath);
323     return titlePath + titleName + ".png";
324 }
325
326 //virtual
327 void TitleWidget::resizeEvent(QResizeEvent * /*event*/)
328 {
329     //slotAdjustZoom();
330 }
331
332 void TitleWidget::slotTextTool()
333 {
334     m_scene->setTool(TITLE_TEXT);
335     showToolbars(TITLE_TEXT);
336     checkButton(TITLE_TEXT);
337 }
338
339 void TitleWidget::slotRectTool()
340 {
341     m_scene->setTool(TITLE_RECTANGLE);
342     showToolbars(TITLE_RECTANGLE);
343     checkButton(TITLE_RECTANGLE);
344 }
345
346 void TitleWidget::slotSelectTool()
347 {
348     m_scene->setTool(TITLE_SELECT);
349
350     // Find out which toolbars need to be shown, depending on selected item
351     TITLETOOL t = TITLE_SELECT;
352     QList<QGraphicsItem *> l = graphicsView->scene()->selectedItems();
353     if (l.size() > 0) {
354         switch (l.at(0)->type()) {
355         case TEXTITEM:
356             t = TITLE_TEXT;
357             break;
358         case RECTITEM:
359             t = TITLE_RECTANGLE;
360             break;
361         case IMAGEITEM:
362             t = TITLE_IMAGE;
363             break;
364         }
365     }
366     enableToolbars(t);
367     showToolbars(t);
368
369     if (l.size() > 0) {
370         updateCoordinates(l.at(0));
371         updateDimension(l.at(0));
372         updateRotZoom(l.at(0));
373     }
374
375     checkButton(TITLE_SELECT);
376 }
377
378 void TitleWidget::slotImageTool()
379 {
380     KUrl url = KFileDialog::getOpenUrl(KUrl(), "*.svg *.png *.jpg *.jpeg *.gif *.raw", this, i18n("Load Image"));
381     if (!url.isEmpty()) {
382         if (url.path().endsWith(".svg")) {
383             QGraphicsSvgItem *svg = new QGraphicsSvgItem(url.toLocalFile());
384             svg->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
385             svg->setZValue(m_count++);
386             svg->setData(Qt::UserRole, url.path());
387             graphicsView->scene()->addItem(svg);
388         } else {
389             QPixmap pix(url.path());
390             QGraphicsPixmapItem *image = new QGraphicsPixmapItem(pix);
391             image->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
392             image->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
393             image->setData(Qt::UserRole, url.path());
394             image->setZValue(m_count++);
395             graphicsView->scene()->addItem(image);
396         }
397     }
398     m_scene->setTool(TITLE_SELECT);
399     showToolbars(TITLE_SELECT);
400     checkButton(TITLE_NONE);
401 }
402
403 void TitleWidget::showToolbars(TITLETOOL toolType)
404 {
405     switch (toolType) {
406     case TITLE_TEXT:
407         rect_properties->setHidden(true);
408         image_properties->setHidden(true);
409         no_properties->setHidden(true);
410         text_properties->setHidden(false);
411         break;
412     case TITLE_RECTANGLE:
413         image_properties->setHidden(true);
414         no_properties->setHidden(true);
415         text_properties->setHidden(true);
416         rect_properties->setHidden(false);
417         break;
418     case TITLE_IMAGE:
419         no_properties->setHidden(true);
420         text_properties->setHidden(true);
421         rect_properties->setHidden(true);
422         image_properties->setHidden(false);
423         break;
424     default:
425         text_properties->setHidden(true);
426         rect_properties->setHidden(true);
427         image_properties->setHidden(true);
428         no_properties->setHidden(false);
429         break;
430     }
431 }
432
433 void TitleWidget::enableToolbars(TITLETOOL toolType)
434 {
435     // TITLETOOL is defined in graphicsscenerectmove.h
436     bool bFrame = false;
437     bool bText = false;
438     bool bRect = false;
439     bool bImage = false;
440     bool bValue_w = false;
441     bool bValue_h = false;
442
443     switch (toolType) {
444     case TITLE_SELECT:
445         break;
446     case TITLE_TEXT:
447         bFrame = true;
448         bText = true;
449         break;
450     case TITLE_RECTANGLE:
451         bFrame = true;
452         bRect = true;
453         bValue_w = true;
454         bValue_h = true;
455         break;
456     case TITLE_IMAGE:
457         bFrame = true;
458         bValue_w = true;
459         bValue_h = true;
460         bImage = true;
461         break;
462     default:
463         break;
464     }
465     frame_properties->setEnabled(bFrame);
466     text_properties->setEnabled(bText);
467     rect_properties->setEnabled(bRect);
468     image_properties->setEnabled(bImage);
469     value_w->setEnabled(bValue_w);
470     value_h->setEnabled(bValue_h);
471 }
472
473 void TitleWidget::checkButton(TITLETOOL toolType)
474 {
475     bool bSelect = false;
476     bool bText = false;
477     bool bRect = false;
478     bool bImage = false;
479
480     switch (toolType) {
481     case TITLE_SELECT:
482         bSelect = true;
483         break;
484     case TITLE_TEXT:
485         bText = true;
486         break;
487     case TITLE_RECTANGLE:
488         bRect = true;
489         break;
490     case TITLE_IMAGE:
491         bImage = true;
492         break;
493     case TITLE_NONE:
494         break;
495     }
496
497     m_buttonCursor->setChecked(bSelect);
498     m_buttonText->setChecked(bText);
499     m_buttonRect->setChecked(bRect);
500     m_buttonImage->setChecked(bImage);
501 }
502
503 void TitleWidget::displayBackgroundFrame()
504 {
505     if (!displayBg->isChecked()) {
506         QPixmap bg(m_frameWidth / 2, m_frameHeight / 2);
507         QPixmap pattern(20, 20);
508         pattern.fill();
509         QPainter p;
510         p.begin(&pattern);
511         p.fillRect(QRect(0, 0, 10, 10), QColor(210, 210, 210));
512         p.fillRect(QRect(10, 10, 20, 20), QColor(210, 210, 210));
513         p.end();
514         QBrush br(pattern);
515
516         p.begin(&bg);
517         p.fillRect(bg.rect(), br);
518         p.end();
519         m_frameImage->setPixmap(bg);
520     } else {
521         m_frameImage->setPixmap(m_render->extractFrame((int) m_render->seekPosition().frames(m_render->fps()), m_frameWidth / 2, m_frameHeight / 2));
522     }
523 }
524
525 void TitleWidget::initViewports()
526 {
527     m_startViewport = new QGraphicsPolygonItem(QPolygonF(QRectF(0, 0, 0, 0)));
528     m_endViewport = new QGraphicsPolygonItem(QPolygonF(QRectF(0, 0, 0, 0)));
529
530     QPen startpen(Qt::DotLine);
531     QPen endpen(Qt::DashDotLine);
532     startpen.setColor(QColor(100, 200, 100, 140));
533     endpen.setColor(QColor(200, 100, 100, 140));
534
535     m_startViewport->setPen(startpen);
536     m_endViewport->setPen(endpen);
537
538     startViewportSize->setValue(100);
539     endViewportSize->setValue(100);
540
541     m_startViewport->setZValue(-1000);
542     m_endViewport->setZValue(-1000);
543
544     m_startViewport->setFlags(/*QGraphicsItem::ItemIsMovable|*/QGraphicsItem::ItemIsSelectable);
545     m_endViewport->setFlags(/*QGraphicsItem::ItemIsMovable|*/QGraphicsItem::ItemIsSelectable);
546
547     graphicsView->scene()->addItem(m_startViewport);
548     graphicsView->scene()->addItem(m_endViewport);
549 }
550
551 void TitleWidget::slotUpdateZoom(int pos)
552 {
553     m_scene->setZoom((double) pos / 100);
554     zoom_label->setText(QString::number(pos) + '%');
555 }
556
557 void TitleWidget::slotZoom(bool up)
558 {
559     int pos = zoom_slider->value();
560     if (up) pos++;
561     else pos--;
562     zoom_slider->setValue(pos);
563 }
564
565 void TitleWidget::slotAdjustZoom()
566 {
567     /*double scalex = graphicsView->width() / (double)(m_frameWidth * 1.2);
568     double scaley = graphicsView->height() / (double)(m_frameHeight * 1.2);
569     if (scalex > scaley) scalex = scaley;
570     int zoompos = (int)(scalex * 7 + 0.5);*/
571     graphicsView->fitInView(m_frameBorder, Qt::KeepAspectRatio);
572     int zoompos = graphicsView->matrix().m11() * 100;
573     zoom_slider->setValue(zoompos);
574     graphicsView->centerOn(m_frameBorder);
575 }
576
577 void TitleWidget::slotZoomOneToOne()
578 {
579     zoom_slider->setValue(100);
580     graphicsView->centerOn(m_frameBorder);
581 }
582
583 void TitleWidget::slotNewRect(QGraphicsRectItem * rect)
584 {
585     updateAxisButtons(rect); // back to default
586
587     QColor f = rectFColor->color();
588     f.setAlpha(rectFAlpha->value());
589     QPen penf(f);
590     penf.setWidth(rectLineWidth->value());
591     rect->setPen(penf);
592     QColor b = rectBColor->color();
593     b.setAlpha(rectBAlpha->value());
594     rect->setBrush(QBrush(b));
595     rect->setZValue(m_count++);
596     //setCurrentItem(rect);
597     //graphicsView->setFocus();
598 }
599
600 void TitleWidget::slotNewText(QGraphicsTextItem *tt)
601 {
602     updateAxisButtons(tt); // back to default
603
604     QFont font = font_family->currentFont();
605     font.setPixelSize(font_size->value());
606     // mbd: issue 551:
607     font.setWeight(font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
608     font.setItalic(buttonItalic->isChecked());
609     font.setUnderline(buttonUnder->isChecked());
610
611     tt->setFont(font);
612     QColor color = fontColorButton->color();
613     color.setAlpha(textAlpha->value());
614     tt->setDefaultTextColor(color);
615     tt->setZValue(m_count++);
616     setCurrentItem(tt);
617 }
618
619 void TitleWidget::setFontBoxWeight(int weight)
620 {
621     int index = font_weight_box->findData(weight);
622     if (index < 0) {
623         index = font_weight_box->findData(QFont::Normal);
624     }
625     font_weight_box->setCurrentIndex(index);
626 }
627
628 void TitleWidget::setCurrentItem(QGraphicsItem *item)
629 {
630     m_scene->setSelectedItem(item);
631 }
632
633 void TitleWidget::zIndexChanged(int v)
634 {
635     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
636     if (l.size() >= 1) {
637         l[0]->setZValue(v);
638     }
639 }
640
641 void TitleWidget::selectionChanged()
642 {
643     if (m_scene->tool() != TITLE_SELECT) return;
644     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
645     //toolBox->setItemEnabled(2, false);
646     //toolBox->setItemEnabled(3, false);
647     value_x->blockSignals(true);
648     value_y->blockSignals(true);
649     value_w->blockSignals(true);
650     value_h->blockSignals(true);
651     itemzoom->blockSignals(true);
652     itemrotate->blockSignals(true);
653     if (l.size() == 0) {
654         bool blockX = !origin_x_left->signalsBlocked();
655         bool blockY = !origin_y_top->signalsBlocked();
656         if (blockX) origin_x_left->blockSignals(true);
657         if (blockY) origin_y_top->blockSignals(true);
658         origin_x_left->setChecked(false);
659         origin_y_top->setChecked(false);
660         updateTextOriginX();
661         updateTextOriginY();
662         enableToolbars(TITLE_NONE);
663         if (blockX) origin_x_left->blockSignals(false);
664         if (blockY) origin_y_top->blockSignals(false);
665     } else if (l.size() == 1) {
666         if (l.at(0)->type() == TEXTITEM) {
667             showToolbars(TITLE_TEXT);
668             QGraphicsTextItem* i = static_cast <QGraphicsTextItem *>(l.at(0));
669             //if (l[0]->hasFocus())
670             toolBox->setCurrentIndex(0);
671             //toolBox->setItemEnabled(2, true);
672             font_size->blockSignals(true);
673             font_family->blockSignals(true);
674             font_weight_box->blockSignals(true);
675             buttonItalic->blockSignals(true);
676             buttonUnder->blockSignals(true);
677             fontColorButton->blockSignals(true);
678             textAlpha->blockSignals(true);
679             buttonAlignLeft->blockSignals(true);
680             buttonAlignRight->blockSignals(true);
681             buttonAlignNone->blockSignals(true);
682             buttonAlignCenter->blockSignals(true);
683
684             QFont font = i->font();
685             font_family->setCurrentFont(font);
686             font_size->setValue(font.pixelSize());
687             buttonItalic->setChecked(font.italic());
688             buttonUnder->setChecked(font.underline());
689             setFontBoxWeight(font.weight());
690
691             QColor color = i->defaultTextColor();
692             fontColorButton->setColor(color);
693             textAlpha->setValue(color.alpha());
694
695             QTextCursor cur = i->textCursor();
696             QTextBlockFormat format = cur.blockFormat();
697             if (i->textWidth() == -1) buttonAlignNone->setChecked(true);
698             else if (format.alignment() == Qt::AlignHCenter) buttonAlignCenter->setChecked(true);
699             else if (format.alignment() == Qt::AlignRight) buttonAlignRight->setChecked(true);
700             else if (format.alignment() == Qt::AlignLeft) buttonAlignLeft->setChecked(true);
701
702             font_size->blockSignals(false);
703             font_family->blockSignals(false);
704             font_weight_box->blockSignals(false);
705             buttonItalic->blockSignals(false);
706             buttonUnder->blockSignals(false);
707             fontColorButton->blockSignals(false);
708             textAlpha->blockSignals(false);
709             buttonAlignLeft->blockSignals(false);
710             buttonAlignRight->blockSignals(false);
711             buttonAlignNone->blockSignals(false);
712             buttonAlignCenter->blockSignals(false);
713
714             updateAxisButtons(i);
715             updateCoordinates(i);
716             updateDimension(i);
717             enableToolbars(TITLE_TEXT);
718
719         } else if ((l.at(0))->type() == RECTITEM) {
720             showToolbars(TITLE_RECTANGLE);
721             settingUp = true;
722             QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(l.at(0));
723             toolBox->setCurrentIndex(0);
724             //toolBox->setItemEnabled(3, true);
725             rectFAlpha->setValue(rec->pen().color().alpha());
726             rectBAlpha->setValue(rec->brush().color().alpha());
727             //kDebug() << rec->brush().color().alpha();
728             QColor fcol = rec->pen().color();
729             QColor bcol = rec->brush().color();
730             //fcol.setAlpha(255);
731             //bcol.setAlpha(255);
732             rectFColor->setColor(fcol);
733             rectBColor->setColor(bcol);
734             settingUp = false;
735             rectLineWidth->setValue(rec->pen().width());
736
737             updateAxisButtons(l.at(0));
738             updateCoordinates(rec);
739             updateDimension(rec);
740             enableToolbars(TITLE_RECTANGLE);
741
742         } else if (l.at(0)->type() == IMAGEITEM) {
743             showToolbars(TITLE_IMAGE);
744
745             updateCoordinates(l.at(0));
746             updateDimension(l.at(0));
747
748             enableToolbars(TITLE_IMAGE);
749
750         } else {
751             //toolBox->setCurrentIndex(0);
752             showToolbars(TITLE_NONE);
753             enableToolbars(TITLE_NONE);
754             /*frame_properties->setEnabled(false);
755             text_properties->setEnabled(false);
756             rect_properties->setEnabled(false);*/
757         }
758         zValue->setValue((int)l.at(0)->zValue());
759         itemzoom->setValue((int)(m_transformations.value(l.at(0)).scalex * 100.0 + 0.5));
760         itemrotate->setValue((int)(m_transformations.value(l.at(0)).rotate));
761         value_x->blockSignals(false);
762         value_y->blockSignals(false);
763         value_w->blockSignals(false);
764         value_h->blockSignals(false);
765         itemzoom->blockSignals(false);
766         itemrotate->blockSignals(false);
767     }
768 }
769
770 void TitleWidget::slotValueChanged(int type)
771 {
772     QList<QGraphicsItem *> l = graphicsView->scene()->selectedItems();
773     if (l.size() > 0 && l.at(0)->type() == IMAGEITEM) {
774
775         int val = 0;
776         switch (type) {
777         case ValueWidth:
778             val = value_w->value();
779             break;
780         case ValueHeight:
781             val = value_h->value();
782             break;
783         }
784
785         QGraphicsItem *i = l.at(0);
786         Transform t = m_transformations.value(i);
787
788         // Ratio width:height
789         double phi = (double) i->boundingRect().width() / i->boundingRect().height();
790         double alpha = (double) t.rotate / 180.0 * M_PI;
791
792         // New length
793         double length = val;
794
795         // Scaling factor
796         double scale = 1;
797
798         switch (type) {
799         case ValueWidth:
800             // Add 0.5 because otherwise incrementing by 1 might have no effect
801             length = val / (cos(alpha) + 1 / phi * sin(alpha)) + 0.5;
802             scale = length / i->boundingRect().width();
803             break;
804         case ValueHeight:
805             length = val / (phi * sin(alpha) + cos(alpha)) + 0.5;
806             scale = length / i->boundingRect().height();
807             break;
808         }
809
810         t.scalex = scale;
811         t.scaley = scale;
812         QTransform qtrans;
813         qtrans.scale(scale, scale);
814         qtrans.rotate(t.rotate);
815         i->setTransform(qtrans);
816         m_transformations[i] = t;
817
818         updateDimension(i);
819         updateRotZoom(i);
820     }
821 }
822
823 /** \brief Updates position/size of the selected item when a value
824  * of an item (coordinates, size) has changed */
825 void TitleWidget::slotAdjustSelectedItem()
826 {
827     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
828     if (l.size() >= 1) {
829         if (l.at(0)->type() == RECTITEM) {
830             //rect item
831             QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(l.at(0));
832             updatePosition(rec);
833             rec->setRect(QRect(0, 0, value_w->value(), value_h->value()));
834         } else if (l.at(0)->type() == TEXTITEM) {
835             //text item
836             updatePosition(l.at(0));
837         } else if (l.at(0)->type() == IMAGEITEM) {
838             //image item
839             updatePosition(l.at(0));
840         }
841     }
842 }
843
844 /** \brief Updates width/height int the text fields, regarding transformation matrix */
845 void TitleWidget::updateDimension(QGraphicsItem *i)
846 {
847     value_w->blockSignals(true);
848     value_h->blockSignals(true);
849
850
851     if (i->type() == IMAGEITEM) {
852         // Get multipliers for rotation/scaling
853
854         /*Transform t = m_transformations.value(i);
855         QRectF r = i->boundingRect();
856         int width = (int) ( abs(r.width()*t.scalex * cos(t.rotate/180.0*M_PI))
857                     + abs(r.height()*t.scaley * sin(t.rotate/180.0*M_PI)) );
858         int height = (int) ( abs(r.height()*t.scaley * cos(t.rotate/180*M_PI))
859                     + abs(r.width()*t.scalex * sin(t.rotate/180*M_PI)) );*/
860
861         value_w->setValue(i->sceneBoundingRect().width());
862         value_h->setValue(i->sceneBoundingRect().height());
863     } else if (i->type() == RECTITEM) {
864         QGraphicsRectItem *r = static_cast <QGraphicsRectItem *>(i);
865         value_w->setValue((int) r->rect().width());
866         value_h->setValue((int) r->rect().height());
867     } else if (i->type() == TEXTITEM) {
868         QGraphicsTextItem *t = static_cast <QGraphicsTextItem *>(i);
869         value_w->setValue((int) t->boundingRect().width());
870         value_h->setValue((int) t->boundingRect().height());
871     }
872
873     value_w->blockSignals(false);
874     value_h->blockSignals(false);
875 }
876
877 /** \brief Updates the coordinates in the text fields from the item */
878 void TitleWidget::updateCoordinates(QGraphicsItem *i)
879 {
880     // Block signals emitted by this method
881     value_x->blockSignals(true);
882     value_y->blockSignals(true);
883
884     if (i->type() == TEXTITEM) {
885
886         QGraphicsTextItem *rec = static_cast <QGraphicsTextItem *>(i);
887
888         // Set the correct x coordinate value
889         if (origin_x_left->isChecked()) {
890             // Origin (0 point) is at m_frameWidth, coordinate axis is inverted
891             value_x->setValue((int)(m_frameWidth - rec->pos().x() - rec->boundingRect().width()));
892         } else {
893             // Origin is at 0 (default)
894             value_x->setValue((int) rec->pos().x());
895         }
896
897         // Same for y
898         if (origin_y_top->isChecked()) {
899             value_y->setValue((int)(m_frameHeight - rec->pos().y() - rec->boundingRect().height()));
900         } else {
901             value_y->setValue((int) rec->pos().y());
902         }
903
904     } else if (i->type() == RECTITEM) {
905
906         QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(i);
907
908         if (origin_x_left->isChecked()) {
909             // Origin (0 point) is at m_frameWidth
910             value_x->setValue((int)(m_frameWidth - rec->pos().x() - rec->rect().width()));
911         } else {
912             // Origin is at 0 (default)
913             value_x->setValue((int) rec->pos().x());
914         }
915
916         if (origin_y_top->isChecked()) {
917             value_y->setValue((int)(m_frameHeight - rec->pos().y() - rec->rect().height()));
918         } else {
919             value_y->setValue((int) rec->pos().y());
920         }
921
922     } else if (i->type() == IMAGEITEM) {
923
924         if (origin_x_left->isChecked()) {
925             value_x->setValue((int)(m_frameWidth - i->pos().x() - i->sceneBoundingRect().width()));
926         } else {
927             value_x->setValue((int) i->pos().x());
928         }
929
930         if (origin_y_top->isChecked()) {
931             value_y->setValue((int)(m_frameHeight - i->pos().y() - i->sceneBoundingRect().height()));
932         } else {
933             value_y->setValue((int) i->pos().y());
934         }
935
936     }
937
938     // Stop blocking signals now
939     value_x->blockSignals(false);
940     value_y->blockSignals(false);
941 }
942
943 void TitleWidget::updateRotZoom(QGraphicsItem *i)
944 {
945     itemzoom->blockSignals(true);
946     itemrotate->blockSignals(false);
947
948     Transform t = m_transformations.value(i);
949     itemzoom->setValue((int)(t.scalex * 100.0 + 0.5));
950     itemrotate->setValue((int)(t.rotate));
951
952     itemzoom->blockSignals(false);
953     itemrotate->blockSignals(false);
954 }
955
956 /** \brief Updates the position of an item by reading coordinates from the text fields */
957 void TitleWidget::updatePosition(QGraphicsItem *i)
958 {
959     if (i->type() == TEXTITEM) {
960         QGraphicsTextItem *rec = static_cast <QGraphicsTextItem *>(i);
961
962         int posX;
963         if (origin_x_left->isChecked()) {
964             /* Origin of the x axis is at m_frameWidth,
965              * and distance from right border of the item to the right
966              * border of the frame is taken.
967              * See comment to slotOriginXClicked().
968              */
969             posX = m_frameWidth - value_x->value() - rec->boundingRect().width();
970         } else {
971             posX = value_x->value();
972         }
973
974         int posY;
975         if (origin_y_top->isChecked()) {
976             /* Same for y axis */
977             posY = m_frameHeight - value_y->value() - rec->boundingRect().height();
978         } else {
979             posY = value_y->value();
980         }
981
982         rec->setPos(posX, posY);
983
984     } else if (i->type() == RECTITEM) {
985
986         QGraphicsRectItem *rec = static_cast <QGraphicsRectItem *>(i);
987
988         int posX;
989         if (origin_x_left->isChecked()) {
990             posX = m_frameWidth - value_x->value() - rec->rect().width();
991         } else {
992             posX = value_x->value();
993         }
994
995         int posY;
996         if (origin_y_top->isChecked()) {
997             posY = m_frameHeight - value_y->value() - rec->rect().height();
998         } else {
999             posY = value_y->value();
1000         }
1001
1002         rec->setPos(posX, posY);
1003
1004     } else if (i->type() == IMAGEITEM) {
1005         int posX;
1006         if (origin_x_left->isChecked()) {
1007             // Use the sceneBoundingRect because this also regards transformations like zoom
1008             posX = m_frameWidth - value_x->value() - i->sceneBoundingRect().width();
1009         } else {
1010             posX = value_x->value();
1011         }
1012
1013         int posY;
1014         if (origin_y_top->isChecked()) {
1015             posY = m_frameHeight - value_y->value() - i->sceneBoundingRect().height();
1016         } else {
1017             posY = value_y->value();
1018         }
1019
1020         i->setPos(posX, posY);
1021
1022     }
1023
1024 }
1025
1026 void TitleWidget::updateTextOriginX()
1027 {
1028     if (origin_x_left->isChecked()) {
1029         origin_x_left->setText(i18n("\u2212X"));
1030     } else {
1031         origin_x_left->setText(i18n("+X"));
1032     }
1033 }
1034
1035 void TitleWidget::slotOriginXClicked()
1036 {
1037     // Update the text displayed on the button.
1038     updateTextOriginX();
1039
1040     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1041     if (l.size() >= 1) {
1042         updateCoordinates(l.at(0));
1043
1044         // Remember x axis setting
1045         l.at(0)->setData(TitleDocument::OriginXLeft, origin_x_left->isChecked() ?
1046                          TitleDocument::AxisInverted : TitleDocument::AxisDefault);
1047     }
1048     graphicsView->setFocus();
1049 }
1050
1051 void TitleWidget::updateTextOriginY()
1052 {
1053     if (origin_y_top->isChecked()) {
1054         origin_y_top->setText(i18n("\u2212Y"));
1055     } else {
1056         origin_y_top->setText(i18n("+Y"));
1057     }
1058 }
1059
1060 void TitleWidget::slotOriginYClicked()
1061 {
1062     // Update the text displayed on the button.
1063     updateTextOriginY();
1064
1065     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1066     if (l.size() >= 1) {
1067         updateCoordinates(l.at(0));
1068
1069         l.at(0)->setData(TitleDocument::OriginYTop, origin_y_top->isChecked() ?
1070                          TitleDocument::AxisInverted : TitleDocument::AxisDefault);
1071
1072     }
1073     graphicsView->setFocus();
1074 }
1075
1076 void TitleWidget::updateAxisButtons(QGraphicsItem *i)
1077 {
1078     int xAxis = i->data(TitleDocument::OriginXLeft).toInt();
1079     int yAxis = i->data(TitleDocument::OriginYTop).toInt();
1080     origin_x_left->blockSignals(true);
1081     origin_y_top->blockSignals(true);
1082
1083     if (xAxis == TitleDocument::AxisInverted) {
1084         origin_x_left->setChecked(true);
1085     } else {
1086         origin_x_left->setChecked(false);
1087     }
1088     updateTextOriginX();
1089
1090     if (yAxis == TitleDocument::AxisInverted) {
1091         origin_y_top->setChecked(true);
1092     } else {
1093         origin_y_top->setChecked(false);
1094     }
1095     updateTextOriginY();
1096
1097     origin_x_left->blockSignals(false);
1098     origin_y_top->blockSignals(false);
1099 }
1100
1101 void TitleWidget::slotChangeBackground()
1102 {
1103     QColor color = kcolorbutton->color();
1104     color.setAlpha(horizontalSlider->value());
1105     m_frameBorder->setBrush(QBrush(color));
1106 }
1107
1108 /**
1109  * Something (yeah) has changed in our QGraphicsScene.
1110  */
1111 void TitleWidget::slotChanged()
1112 {
1113     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1114     if (l.size() >= 1 && l.at(0)->type() == TEXTITEM) {
1115         textChanged(static_cast <QGraphicsTextItem *>(l.at(0)));
1116     }
1117 }
1118
1119 /**
1120  * If the user has set origin_x_left (everything also for y),
1121  * we need to look whether a text element has been selected. If yes,
1122  * we need to ensure that the right border of the text field
1123  * remains fixed also when some text has been entered.
1124  *
1125  * This is also known as right-justified, with the difference that
1126  * it is not valid for text but for its boundingRect. Text may still
1127  * be left-justified.
1128  */
1129 void TitleWidget::textChanged(QGraphicsTextItem *i)
1130 {
1131
1132     updateDimension(i);
1133
1134     if (origin_x_left->isChecked() || origin_y_top->isChecked()) {
1135
1136         if (!i->toPlainText().isEmpty()) {
1137             updatePosition(i);
1138         } else {
1139             /*
1140              * Don't do anything if the string is empty. If the position
1141              * would be updated here, a newly created text field would
1142              * be set to the position of the last selected text field.
1143              */
1144         }
1145     }
1146 }
1147
1148 void TitleWidget::slotInsertUnicode()
1149 {
1150     m_unicodeDialog->exec();
1151 }
1152
1153 void TitleWidget::slotInsertUnicodeString(QString text)
1154 {
1155     QList<QGraphicsItem *> l = graphicsView->scene()->selectedItems();
1156     if (l.size() > 0) {
1157         if (l.at(0)->type() == TEXTITEM) {
1158             QGraphicsTextItem *t = static_cast <QGraphicsTextItem *>(l.at(0));
1159             t->textCursor().insertText(text);
1160         }
1161     }
1162 }
1163
1164 void TitleWidget::slotUpdateText()
1165 {
1166     QFont font = font_family->currentFont();
1167     font.setPixelSize(font_size->value());
1168     font.setItalic(buttonItalic->isChecked());
1169     font.setUnderline(buttonUnder->isChecked());
1170     font.setWeight(font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
1171     QColor color = fontColorButton->color();
1172     color.setAlpha(textAlpha->value());
1173
1174     QGraphicsTextItem* item = NULL;
1175     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1176     if (l.size() == 1 && l.at(0)->type() == TEXTITEM) {
1177         item = static_cast <QGraphicsTextItem *>(l.at(0));
1178     }
1179     if (!item) return;
1180     //if (item->textCursor().selection ().isEmpty())
1181     QTextCursor cur = item->textCursor();
1182     QTextBlockFormat format = cur.blockFormat();
1183     if (buttonAlignLeft->isChecked() || buttonAlignCenter->isChecked() || buttonAlignRight->isChecked()) {
1184         item->setTextWidth(item->boundingRect().width());
1185         if (buttonAlignCenter->isChecked()) format.setAlignment(Qt::AlignHCenter);
1186         else if (buttonAlignRight->isChecked()) format.setAlignment(Qt::AlignRight);
1187         else if (buttonAlignLeft->isChecked()) format.setAlignment(Qt::AlignLeft);
1188     } else {
1189         format.setAlignment(Qt::AlignLeft);
1190         item->setTextWidth(-1);
1191     }
1192
1193     {
1194         item->setFont(font);
1195         item->setDefaultTextColor(color);
1196         cur.select(QTextCursor::Document);
1197         cur.setBlockFormat(format);
1198         item->setTextCursor(cur);
1199         cur.clearSelection();
1200         item->setTextCursor(cur);
1201
1202     }
1203 }
1204
1205 void TitleWidget::rectChanged()
1206 {
1207     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1208     if (l.size() == 1 && l.at(0)->type() == RECTITEM && !settingUp) {
1209         QGraphicsRectItem *rec = static_cast<QGraphicsRectItem *>(l.at(0));
1210         QColor f = rectFColor->color();
1211         f.setAlpha(rectFAlpha->value());
1212         QPen penf(f);
1213         penf.setWidth(rectLineWidth->value());
1214         rec->setPen(penf);
1215         QColor b = rectBColor->color();
1216         b.setAlpha(rectBAlpha->value());
1217         rec->setBrush(QBrush(b));
1218     }
1219 }
1220
1221 void TitleWidget::itemScaled(int val)
1222 {
1223     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1224     if (l.size() == 1) {
1225         Transform x = m_transformations.value(l.at(0));
1226         x.scalex = (double)val / 100.0;
1227         x.scaley = (double)val / 100.0;
1228         QTransform qtrans;
1229         qtrans.scale(x.scalex, x.scaley);
1230         qtrans.rotate(x.rotate);
1231         l[0]->setTransform(qtrans);
1232         m_transformations[l.at(0)] = x;
1233         updateDimension(l.at(0));
1234     }
1235 }
1236
1237 void TitleWidget::itemRotate(int val)
1238 {
1239     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1240     if (l.size() == 1) {
1241         Transform x = m_transformations[l.at(0)];
1242         x.rotate = (double)val;
1243         QTransform qtrans;
1244         qtrans.scale(x.scalex, x.scaley);
1245         qtrans.rotate(x.rotate);
1246         l[0]->setTransform(qtrans);
1247         m_transformations[l.at(0)] = x;
1248         updateDimension(l.at(0));
1249     }
1250 }
1251
1252 void TitleWidget::itemHCenter()
1253 {
1254     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1255     if (l.size() == 1) {
1256         QGraphicsItem *item = l.at(0);
1257         QRectF br;
1258         br = item->sceneBoundingRect();
1259         int width = (int)br.width();
1260         int newPos = (int)((m_frameWidth - width) / 2);
1261         newPos += item->pos().x() - br.left(); // Check item transformation
1262         item->setPos(newPos, item->pos().y());
1263         updateCoordinates(item);
1264     }
1265 }
1266
1267 void TitleWidget::itemVCenter()
1268 {
1269     QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
1270     if (l.size() == 1) {
1271         QGraphicsItem *item = l.at(0);
1272         QRectF br;
1273         br = item->sceneBoundingRect();
1274         int height = (int)br.height();
1275         int newPos = (int)((m_frameHeight - height) / 2);
1276         newPos += item->pos().y() - br.top(); // Check item transformation
1277         item->setPos(item->pos().x(), newPos);
1278         updateCoordinates(item);
1279     }
1280 }
1281
1282 void TitleWidget::setupViewports()
1283 {
1284     //double aspect_ratio = 4.0 / 3.0;//read from project
1285     //better zoom centered, but render uses only the created rect, so no problem to change the zoom function
1286     QRectF sp(0, 0, startViewportSize->value() * m_frameWidth / 100.0 , startViewportSize->value()* m_frameHeight / 100.0);
1287     QRectF ep(0, 0, endViewportSize->value() * m_frameWidth / 100.0, endViewportSize->value() * m_frameHeight / 100.0);
1288     // use a polygon thiat uses 16:9 and 4:3 rects forpreview the size in all aspect ratios ?
1289     QPolygonF spoly(sp);
1290     QPolygonF epoly(ep);
1291     spoly.translate(startViewportX->value(), startViewportY->value());
1292     epoly.translate(endViewportX->value(), endViewportY->value());
1293     m_startViewport->setPolygon(spoly);
1294     m_endViewport->setPolygon(epoly);
1295     if (! insertingValues) {
1296         m_startViewport->setData(0, startViewportX->value());
1297         m_startViewport->setData(1, startViewportY->value());
1298         m_startViewport->setData(2, startViewportSize->value());
1299
1300         m_endViewport->setData(0, endViewportX->value());
1301         m_endViewport->setData(1, endViewportY->value());
1302         m_endViewport->setData(2, endViewportSize->value());
1303     }
1304 }
1305
1306 void TitleWidget::loadTitle()
1307 {
1308     KUrl url = KFileDialog::getOpenUrl(KUrl(m_projectTitlePath), "*.kdenlivetitle", this, i18n("Load Title"));
1309     if (!url.isEmpty()) {
1310         QList<QGraphicsItem *> items = m_scene->items();
1311         for (int i = 0; i < items.size(); i++) {
1312             if (items.at(i)->zValue() > -1000) delete items.at(i);
1313         }
1314         m_scene->clearTextSelection();
1315         double out;
1316         m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport, &out) + 1;
1317         title_duration->setText(m_tc.getTimecode(GenTime(out / 1000.0), m_render->fps()));
1318         insertingValues = true;
1319         startViewportX->setValue(m_startViewport->data(0).toInt());
1320         startViewportY->setValue(m_startViewport->data(1).toInt());
1321         startViewportSize->setValue(m_startViewport->data(2).toInt());
1322         endViewportX->setValue(m_endViewport->data(0).toInt());
1323         endViewportY->setValue(m_endViewport->data(1).toInt());
1324         endViewportSize->setValue(m_endViewport->data(2).toInt());
1325         insertingValues = false;
1326         slotSelectTool();
1327     }
1328 }
1329
1330 void TitleWidget::saveTitle(KUrl url)
1331 {
1332     if (url.isEmpty()) url = KFileDialog::getSaveUrl(KUrl(m_projectTitlePath), "*.kdenlivetitle", this, i18n("Save Title"));
1333     if (!url.isEmpty()) {
1334         if (m_titledocument.saveDocument(url, m_startViewport, m_endViewport, GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).ms()) == false)
1335             KMessageBox::error(this, i18n("Cannot write to file %1", url.path()));
1336     }
1337 }
1338
1339 QDomDocument TitleWidget::xml()
1340 {
1341     QDomDocument doc = m_titledocument.xml(m_startViewport, m_endViewport);
1342     doc.documentElement().setAttribute("out", GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).ms());
1343     if (cropImage->isChecked()) {
1344         doc.documentElement().setAttribute("crop", 1);
1345     }
1346     return doc;
1347 }
1348
1349 int TitleWidget::duration() const
1350 {
1351     return GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).frames(m_render->fps());
1352 }
1353
1354 void TitleWidget::setXml(QDomDocument doc)
1355 {
1356     double out;
1357     m_count = m_titledocument.loadFromXml(doc, m_startViewport, m_endViewport, &out);
1358     kDebug() << "\n\n// TITLE OUT: " << out;
1359     title_duration->setText(m_tc.getTimecode(GenTime(out / 1000.0), m_render->fps()));
1360     /*if (doc.documentElement().hasAttribute("out")) {
1361     GenTime duration = GenTime(doc.documentElement().attribute("out").toDouble() / 1000.0);
1362     title_duration->setText(m_tc.getTimecode(duration, m_render->fps()));
1363     }
1364     else title_duration->setText(m_tc.getTimecode(GenTime(5000), m_render->fps()));*/
1365
1366     QDomElement e = doc.documentElement();
1367     cropImage->setChecked(e.hasAttribute("crop"));
1368     m_transformations.clear();
1369     QList <QGraphicsItem *> items = graphicsView->scene()->items();
1370     const double PI = 4.0 * atan(1.0);
1371     for (int i = 0; i < items.count(); i++) {
1372         QTransform t = items.at(i)->transform();
1373         Transform x;
1374         x.scalex = t.m11();
1375         x.scaley = t.m22();
1376         x.rotate = 180. / PI * atan2(-t.m21(), t.m11());
1377         m_transformations[items.at(i)] = x;
1378     }
1379     // mbd: Update the GUI color selectors to match the stuff from the loaded document
1380     QColor background_color = m_titledocument.getBackgroundColor();
1381     horizontalSlider->blockSignals(true);
1382     kcolorbutton->blockSignals(true);
1383     horizontalSlider->setValue(background_color.alpha());
1384     background_color.setAlpha(255);
1385     kcolorbutton->setColor(background_color);
1386     horizontalSlider->blockSignals(false);
1387     kcolorbutton->blockSignals(false);
1388
1389     slotSelectTool();
1390 }
1391
1392 const QRect TitleWidget::renderedRect()
1393 {
1394     int minX = 0;
1395     int minY = 0;
1396     int maxX = m_frameWidth;
1397     int maxY = m_frameHeight;
1398     if (!cropImage->isChecked()) {
1399         m_scene->removeItem(m_startViewport);
1400         m_scene->removeItem(m_endViewport);
1401         QRect boundingRect = m_scene->itemsBoundingRect().toRect();
1402         if (boundingRect.left() < 0) minX = boundingRect.left();
1403         if (boundingRect.top() < 0) minY = boundingRect.top();
1404         if (boundingRect.right() > maxX) maxX = boundingRect.right();
1405         if (boundingRect.bottom() > maxY) maxY = boundingRect.bottom();
1406         if (minX < 0) {
1407             maxX = maxX - minX;
1408         }
1409         if (minY < 0) {
1410             maxY = maxY - minY;
1411         }
1412     }
1413     QRect rect(minX, minY, maxX, maxY);
1414     return rect;
1415 }
1416
1417 QImage TitleWidget::renderedPixmap()
1418 {
1419     QRect rect = renderedRect();
1420     QImage pix(rect.width(), rect.height(), QImage::Format_ARGB32);
1421     pix.fill(Qt::transparent);
1422     QPainter painter(&pix);
1423     painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing);
1424     m_scene->clearTextSelection();
1425     QPen framepen = m_frameBorder->pen();
1426     m_frameBorder->setPen(Qt::NoPen);
1427     m_startViewport->setVisible(false);
1428     m_endViewport->setVisible(false);
1429     m_frameImage->setVisible(false);
1430
1431     m_scene->render(&painter, QRectF(), rect); //QRectF(minX, minY, maxX - minX, maxY - minY));
1432     painter.end();
1433     m_frameBorder->setPen(framepen);
1434     m_startViewport->setVisible(true);
1435     m_endViewport->setVisible(true);
1436     m_frameImage->setVisible(true);
1437     return pix;
1438 }
1439
1440 /** \brief Connected to the accepted signal - calls writeChoices */
1441 void TitleWidget::slotAccepted()
1442 {
1443     writeChoices();
1444 }
1445
1446 /** \brief Store the current choices of font, background and rect values */
1447 void TitleWidget::writeChoices()
1448 {
1449     // Get a pointer to a shared configuration instance, then get the TitleWidget group.
1450     KSharedConfigPtr config = KGlobal::config();
1451     KConfigGroup titleConfig(config, "TitleWidget");
1452     // Write the entries
1453     titleConfig.writeEntry("font_family", font_family->currentFont());
1454     //titleConfig.writeEntry("font_size", font_size->value());
1455     titleConfig.writeEntry("font_pixel_size", font_size->value());
1456     titleConfig.writeEntry("font_color", fontColorButton->color());
1457     titleConfig.writeEntry("font_alpha", textAlpha->value());
1458     titleConfig.writeEntry("font_weight", font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
1459     titleConfig.writeEntry("font_italic", buttonItalic->isChecked());
1460     titleConfig.writeEntry("font_underlined", buttonUnder->isChecked());
1461
1462     titleConfig.writeEntry("rect_foreground_color", rectFColor->color());
1463     titleConfig.writeEntry("rect_foreground_alpha", rectFAlpha->value());
1464     titleConfig.writeEntry("rect_background_color", rectBColor->color());
1465     titleConfig.writeEntry("rect_background_alpha", rectBAlpha->value());
1466     titleConfig.writeEntry("rect_line_width", rectLineWidth->value());
1467
1468     titleConfig.writeEntry("background_color", kcolorbutton->color());
1469     titleConfig.writeEntry("background_alpha", horizontalSlider->value());
1470
1471     titleConfig.writeEntry("crop_image", cropImage->isChecked());
1472
1473     //! \todo Not sure if I should sync - it is probably safe to do it
1474     config->sync();
1475
1476 }
1477
1478 /** \brief Read the last stored choices into the dialog */
1479 void TitleWidget::readChoices()
1480 {
1481     // Get a pointer to a shared configuration instance, then get the TitleWidget group.
1482     KSharedConfigPtr config = KGlobal::config();
1483     KConfigGroup titleConfig(config, "TitleWidget");
1484     // read the entries
1485     font_family->setCurrentFont(titleConfig.readEntry("font_family", font_family->currentFont()));
1486     font_size->setValue(titleConfig.readEntry("font_pixel_size", font_size->value()));
1487     fontColorButton->setColor(titleConfig.readEntry("font_color", fontColorButton->color()));
1488     textAlpha->setValue(titleConfig.readEntry("font_alpha", textAlpha->value()));
1489     int weight;
1490     if (titleConfig.readEntry("font_bold", false)) weight = QFont::Bold;
1491     else weight = titleConfig.readEntry("font_weight", font_weight_box->itemData(font_weight_box->currentIndex()).toInt());
1492     setFontBoxWeight(weight);
1493     buttonItalic->setChecked(titleConfig.readEntry("font_italic", buttonItalic->isChecked()));
1494     buttonUnder->setChecked(titleConfig.readEntry("font_underlined", buttonUnder->isChecked()));
1495
1496     rectFColor->setColor(titleConfig.readEntry("rect_foreground_color", rectFColor->color()));
1497     rectFAlpha->setValue(titleConfig.readEntry("rect_foreground_alpha", rectFAlpha->value()));
1498     rectBColor->setColor(titleConfig.readEntry("rect_background_color", rectBColor->color()));
1499     rectBAlpha->setValue(titleConfig.readEntry("rect_background_alpha", rectBAlpha->value()));
1500     rectLineWidth->setValue(titleConfig.readEntry("rect_line_width", rectLineWidth->value()));
1501
1502     kcolorbutton->setColor(titleConfig.readEntry("background_color", kcolorbutton->color()));
1503     horizontalSlider->setValue(titleConfig.readEntry("background_alpha", horizontalSlider->value()));
1504
1505     cropImage->setChecked(titleConfig.readEntry("crop_image", cropImage->isChecked()));
1506 }
1507