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