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