1 /***************************************************************************
2 titlewidget.h - description
5 copyright : (C) 2008 by Marco Gittler
6 email : g.marco@freenet.de
7 ***************************************************************************/
9 /***************************************************************************
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. *
16 ***************************************************************************/
20 #include <QGraphicsView>
21 #include <QDomDocument>
22 #include <QGraphicsItem>
23 #include <QGraphicsSvgItem>
24 #include <QTextDocumentFragment>
28 #include <KGlobalSettings>
29 #include <KFileDialog>
31 #include "titlewidget.h"
32 #include "kdenlivesettings.h"
34 int settingUp = false;
36 TitleWidget::TitleWidget(Render *render, QWidget *parent): QDialog(parent), m_frameImage(NULL), m_render(render), m_count(0) {
39 setFont(KGlobalSettings::toolBarFont());
40 //toolBox->setFont(KGlobalSettings::toolBarFont());
41 frame_properties->setEnabled(false);
42 //connect(newTextButton, SIGNAL(clicked()), this, SLOT(slotNewText()));
43 //connect(newRectButton, SIGNAL(clicked()), this, SLOT(slotNewRect()));
44 connect(kcolorbutton, SIGNAL(clicked()), this, SLOT(slotChangeBackground())) ;
45 connect(horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChangeBackground())) ;
46 //connect(ktextedit, SIGNAL(textChanged()), this , SLOT(textChanged()));
47 //connect (fontBold, SIGNAL ( clicked()), this, SLOT( setBold()) ) ;
48 connect(buttonLoad, SIGNAL(clicked()), this, SLOT(loadTitle())) ;
49 connect(buttonSave, SIGNAL(clicked()), this, SLOT(saveTitle())) ;
51 //ktextedit->setHidden(true);
52 connect(fontColorButton, SIGNAL(clicked()), this, SLOT(slotUpdateText())) ;
53 connect(font_family, SIGNAL(currentFontChanged(const QFont &)), this, SLOT(slotUpdateText())) ;
54 connect(font_size, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText())) ;
55 connect(textAlpha, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateText()));
56 //connect (ktextedit, SIGNAL(selectionChanged()), this , SLOT (textChanged()));
58 connect(rectFAlpha, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
59 connect(rectBAlpha, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
60 connect(rectFColor, SIGNAL(clicked()), this, SLOT(rectChanged()));
61 connect(rectBColor, SIGNAL(clicked()), this, SLOT(rectChanged()));
62 connect(rectLineWidth, SIGNAL(valueChanged(int)), this, SLOT(rectChanged()));
64 connect(startViewportX, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
65 connect(startViewportY, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
66 connect(startViewportSize, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
67 connect(endViewportX, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
68 connect(endViewportY, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
69 connect(endViewportSize, SIGNAL(valueChanged(int)), this, SLOT(setupViewports()));
71 connect(zValue, SIGNAL(valueChanged(int)), this, SLOT(zIndexChanged(int)));
72 connect(svgfilename, SIGNAL(urlSelected(const KUrl&)), this, SLOT(svgSelected(const KUrl &)));
73 connect(itemzoom, SIGNAL(valueChanged(int)), this, SLOT(itemScaled(int)));
74 connect(itemrotate, SIGNAL(valueChanged(int)), this, SLOT(itemRotate(int)));
76 connect(value_x, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
77 connect(value_y, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
78 connect(value_w, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
79 connect(value_h, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustSelectedItem()));
80 connect(buttonFitZoom, SIGNAL(clicked()), this, SLOT(slotAdjustZoom()));
81 connect(buttonRealSize, SIGNAL(clicked()), this, SLOT(slotZoomOneToOne()));
82 connect(buttonBold, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
83 connect(buttonItalic, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
84 connect(buttonUnder, SIGNAL(clicked()), this, SLOT(slotUpdateText()));
85 connect(displayBg, SIGNAL(stateChanged(int)), this, SLOT(displayBackgroundFrame()));
87 buttonFitZoom->setIcon(KIcon("zoom-fit-best"));
88 buttonRealSize->setIcon(KIcon("zoom-original"));
89 buttonBold->setIcon(KIcon("format-text-bold"));
90 buttonItalic->setIcon(KIcon("format-text-italic"));
91 buttonUnder->setIcon(KIcon("format-text-underline"));
93 buttonRect->setIcon(KIcon("insert-rect"));
94 buttonText->setIcon(KIcon("insert-text"));
95 buttonImage->setIcon(KIcon("insert-image"));
96 buttonCursor->setIcon(KIcon("select-rectangular"));
97 buttonSave->setIcon(KIcon("document-save"));
98 buttonLoad->setIcon(KIcon("document-open"));
100 connect(buttonRect, SIGNAL(clicked()), this, SLOT(slotRectTool()));
101 connect(buttonText, SIGNAL(clicked()), this, SLOT(slotTextTool()));
102 connect(buttonImage, SIGNAL(clicked()), this, SLOT(slotImageTool()));
103 connect(buttonCursor, SIGNAL(clicked()), this, SLOT(slotSelectTool()));
105 text_properties->setHidden(true);
107 m_scene = new GraphicsSceneRectMove(this);
109 // a gradient background
110 QRadialGradient *gradient = new QRadialGradient(0, 0, 10);
111 gradient->setSpread(QGradient::ReflectSpread);
112 //scene->setBackgroundBrush(*gradient);
114 connect(m_scene, SIGNAL(selectionChanged()), this , SLOT(selectionChanged()));
115 connect(m_scene, SIGNAL(itemMoved()), this , SLOT(selectionChanged()));
116 connect(m_scene, SIGNAL(sceneZoom(bool)), this , SLOT(slotZoom(bool)));
117 connect(m_scene, SIGNAL(actionFinished()), this , SLOT(slotSelectTool()));
118 connect(m_scene, SIGNAL(actionFinished()), this , SLOT(selectionChanged()));
119 connect(m_scene, SIGNAL(newRect(QGraphicsRectItem *)), this , SLOT(slotNewRect(QGraphicsRectItem *)));
120 connect(m_scene, SIGNAL(newText(QGraphicsTextItem *)), this , SLOT(slotNewText(QGraphicsTextItem *)));
121 connect(zoom_slider, SIGNAL(valueChanged(int)), this , SLOT(slotUpdateZoom(int)));
123 graphicsView->setScene(m_scene);
124 m_titledocument.setScene(m_scene);
126 QPen framepen(Qt::DotLine);
127 framepen.setColor(Qt::red);
128 m_frameWidth = render->renderWidth();
129 m_frameHeight = render->renderHeight();
132 m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight));
133 m_frameBorder->setPen(framepen);
134 m_frameBorder->setZValue(-1100);
135 m_frameBorder->setBrush(QColor(0, 0, 0, 0));
136 m_frameBorder->setFlags(QGraphicsItem::ItemClipsToShape);
137 graphicsView->scene()->addItem(m_frameBorder);
141 graphicsView->show();
142 graphicsView->setRenderHint(QPainter::Antialiasing);
143 graphicsView->setInteractive(true);
144 QTimer::singleShot(500, this, SLOT(slotAdjustZoom()));
145 //graphicsView->resize(400, 300);
146 kDebug() << "// TITLE WIDGWT: " << graphicsView->viewport()->width() << "x" << graphicsView->viewport()->height();
147 toolBox->setItemEnabled(2, false);
148 toolBox->setItemEnabled(3, false);
153 void TitleWidget::resizeEvent(QResizeEvent * event) {
157 void TitleWidget::slotTextTool() {
158 rect_properties->setHidden(true);
159 text_properties->setHidden(false);
160 m_scene->setTool(TITLE_TEXT);
161 buttonRect->setChecked(false);
162 buttonCursor->setChecked(false);
163 buttonImage->setChecked(false);
166 void TitleWidget::slotRectTool() {
167 rect_properties->setHidden(false);
168 text_properties->setHidden(true);
169 m_scene->setTool(TITLE_RECTANGLE);
170 buttonText->setChecked(false);
171 buttonCursor->setChecked(false);
172 buttonImage->setChecked(false);
175 void TitleWidget::slotSelectTool() {
176 m_scene->setTool(TITLE_SELECT);
177 buttonCursor->setChecked(true);
178 buttonText->setChecked(false);
179 buttonRect->setChecked(false);
180 buttonImage->setChecked(false);
183 void TitleWidget::displayBackgroundFrame() {
184 if (m_frameImage) delete m_frameImage;
186 if (!displayBg->isChecked()) return;
187 QPixmap bg = m_render->extractFrame((int) m_render->seekPosition().frames(m_render->fps()), m_frameWidth / 2, m_frameHeight / 2);
188 m_frameImage = new QGraphicsPixmapItem(bg);
190 qtrans.scale(2.0, 2.0);
191 m_frameImage->setTransform(qtrans);
192 m_frameImage->setZValue(-1200);
193 m_frameImage->setFlags(QGraphicsItem::ItemClipsToShape);
194 graphicsView->scene()->addItem(m_frameImage);
197 void TitleWidget::initViewports() {
198 startViewport = new QGraphicsPolygonItem(QPolygonF(QRectF(0, 0, 0, 0)));
199 endViewport = new QGraphicsPolygonItem(QPolygonF(QRectF(0, 0, 0, 0)));
201 QPen startpen(Qt::DotLine);
202 QPen endpen(Qt::DashDotLine);
203 startpen.setColor(QColor(100, 200, 100, 140));
204 endpen.setColor(QColor(200, 100, 100, 140));
206 startViewport->setPen(startpen);
207 endViewport->setPen(endpen);
209 startViewportSize->setValue(40);
210 endViewportSize->setValue(40);
212 startViewport->setZValue(-1000);
213 endViewport->setZValue(-1000);
215 startViewport->setFlags(/*QGraphicsItem::ItemIsMovable|*/QGraphicsItem::ItemIsSelectable);
216 endViewport->setFlags(/*QGraphicsItem::ItemIsMovable|*/QGraphicsItem::ItemIsSelectable);
218 graphicsView->scene()->addItem(startViewport);
219 graphicsView->scene()->addItem(endViewport);
222 void TitleWidget::slotUpdateZoom(int pos) {
223 m_scene->setZoom((double) pos / 7);
224 zoom_label->setText("x" + QString::number((double) pos / 7, 'g', 2));
227 void TitleWidget::slotZoom(bool up) {
228 int pos = zoom_slider->value();
231 zoom_slider->setValue(pos);
234 void TitleWidget::slotAdjustZoom() {
235 double scalex = graphicsView->width() / (double)(m_frameWidth * 1.2);
236 double scaley = graphicsView->height() / (double)(m_frameHeight * 1.2);
237 if (scalex > scaley) scalex = scaley;
238 int zoompos = (int)(scalex * 7 + 0.5);
239 zoom_slider->setValue(zoompos);
240 graphicsView->centerOn(m_frameBorder);
243 void TitleWidget::slotZoomOneToOne() {
244 zoom_slider->setValue(7);
245 graphicsView->centerOn(m_frameBorder);
248 void TitleWidget::slotNewRect(QGraphicsRectItem * rect) {
249 QColor f = rectFColor->color();
250 f.setAlpha(rectFAlpha->value());
252 penf.setWidth(rectLineWidth->value());
254 QColor b = rectBColor->color();
255 b.setAlpha(rectBAlpha->value());
256 rect->setBrush(QBrush(b));
257 rect->setZValue(m_count++);
258 //setCurrentItem(rect);
259 //graphicsView->setFocus();
262 void TitleWidget::slotNewText(QGraphicsTextItem *tt) {
263 QFont font = font_family->currentFont();
264 font.setPointSize(font_size->value());
266 QColor color = fontColorButton->color();
267 color.setAlpha(textAlpha->value());
268 tt->setDefaultTextColor(color);
269 tt->setZValue(m_count++);
273 void TitleWidget::setCurrentItem(QGraphicsItem *item) {
274 m_scene->setSelectedItem(item);
277 void TitleWidget::zIndexChanged(int v) {
278 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
284 void TitleWidget::selectionChanged() {
285 if (m_scene->tool() != TITLE_SELECT) return;
286 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
287 //toolBox->setItemEnabled(2, false);
288 //toolBox->setItemEnabled(3, false);
289 value_x->blockSignals(true);
290 value_y->blockSignals(true);
291 value_w->blockSignals(true);
292 value_h->blockSignals(true);
293 kDebug() << "//////// SELECTION CHANGED; ITEMS: " << l.size();
295 if ((l[0])->type() == 8) {
296 rect_properties->setHidden(true);
297 text_properties->setHidden(false);
298 QGraphicsTextItem* i = ((QGraphicsTextItem*)l[0]);
299 //if (l[0]->hasFocus())
300 //ktextedit->setHtml(i->toHtml());
301 toolBox->setCurrentIndex(0);
302 //toolBox->setItemEnabled(2, true);
303 font_size->blockSignals(true);
304 font_family->blockSignals(true);
305 buttonBold->blockSignals(true);
306 buttonItalic->blockSignals(true);
307 buttonUnder->blockSignals(true);
308 fontColorButton->blockSignals(true);
309 textAlpha->blockSignals(true);
311 QFont font = i->font();
312 font_family->setCurrentFont(font);
313 font_size->setValue(font.pointSize());
314 buttonBold->setChecked(font.bold());
315 buttonItalic->setChecked(font.italic());
316 buttonUnder->setChecked(font.underline());
318 QColor color = i->defaultTextColor();
319 fontColorButton->setColor(color);
320 textAlpha->setValue(color.alpha());
322 font_size->blockSignals(false);
323 font_family->blockSignals(false);
324 buttonBold->blockSignals(false);
325 buttonItalic->blockSignals(false);
326 buttonUnder->blockSignals(false);
327 fontColorButton->blockSignals(false);
328 textAlpha->blockSignals(false);
330 value_x->setValue((int) i->pos().x());
331 value_y->setValue((int) i->pos().y());
332 value_w->setValue((int) i->boundingRect().width());
333 value_h->setValue((int) i->boundingRect().height());
334 frame_properties->setEnabled(true);
335 value_w->setEnabled(false);
336 value_h->setEnabled(false);
337 } else if ((l[0])->type() == 3) {
338 rect_properties->setHidden(false);
339 text_properties->setHidden(true);
341 QGraphicsRectItem *rec = ((QGraphicsRectItem*)l[0]);
342 toolBox->setCurrentIndex(0);
343 //toolBox->setItemEnabled(3, true);
344 rectFAlpha->setValue(rec->pen().color().alpha());
345 rectBAlpha->setValue(rec->brush().color().alpha());
346 kDebug() << rec->brush().color().alpha();
347 QColor fcol = rec->pen().color();
348 QColor bcol = rec->brush().color();
349 //fcol.setAlpha(255);
350 //bcol.setAlpha(255);
351 rectFColor->setColor(fcol);
352 rectBColor->setColor(bcol);
354 rectLineWidth->setValue(rec->pen().width());
355 value_x->setValue((int) rec->pos().x());
356 value_y->setValue((int) rec->pos().y());
357 value_w->setValue((int) rec->rect().width());
358 value_h->setValue((int) rec->rect().height());
359 frame_properties->setEnabled(true);
360 value_w->setEnabled(true);
361 value_h->setEnabled(true);
363 //toolBox->setCurrentIndex(0);
364 frame_properties->setEnabled(false);
366 zValue->setValue((int)l[0]->zValue());
367 itemzoom->setValue((int)transformations[l[0]].scalex*100);
368 itemrotate->setValue((int)transformations[l[0]].rotate);
369 value_x->blockSignals(false);
370 value_y->blockSignals(false);
371 value_w->blockSignals(false);
372 value_h->blockSignals(false);
373 } else frame_properties->setEnabled(false);
376 void TitleWidget::slotAdjustSelectedItem() {
377 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
379 if (l[0]->type() == 3) {
381 QGraphicsRectItem *rec = ((QGraphicsRectItem*)l[0]);
382 rec->setPos(value_x->value(), value_y->value());
383 rec->setRect(QRect(0, 0, value_w->value(), value_h->value()));
384 } else if (l[0]->type() == 8) {
386 QGraphicsTextItem *rec = ((QGraphicsTextItem*)l[0]);
387 rec->setPos(value_x->value(), value_y->value());
392 void TitleWidget::slotChangeBackground() {
393 QColor color = kcolorbutton->color();
394 color.setAlpha(horizontalSlider->value());
395 m_frameBorder->setBrush(QBrush(color));
398 void TitleWidget::textChanged() {
399 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
400 if (l.size() == 1 && (l[0])->type() == 8 && !l[0]->hasFocus()) {
401 //kDebug() << ktextedit->document()->toHtml();
402 //((QGraphicsTextItem*)l[0])->setHtml(ktextedit->toHtml());
406 void TitleWidget::slotUpdateText() {
407 QFont font = font_family->currentFont();
408 font.setPointSize(font_size->value());
409 font.setBold(buttonBold->isChecked());
410 font.setItalic(buttonItalic->isChecked());
411 font.setUnderline(buttonUnder->isChecked());
412 QColor color = fontColorButton->color();
413 color.setAlpha(textAlpha->value());
415 QGraphicsTextItem* item = NULL;
416 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
417 if (l.size() == 1 && (l[0])->type() == 8) {
418 item = (QGraphicsTextItem*)l[0];
421 //if (item->textCursor().selection ().isEmpty())
424 item->setDefaultTextColor(color);
427 QTextDocumentFragment selec = item->textCursor().selection ();
430 //if (ktextedit->textCursor().selectedText().isEmpty()) ktextedit->selectAll();
432 //ktextedit->setCurrentFont(font);
433 //ktextedit->setTextColor(color);
434 /*QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
435 if (l.size() == 1 && (l[0])->type() == 8 && l[0]->hasFocus()) {
436 QGraphicsTextItem* item = static_cast <QGraphicsTextItem*> (l[0]);
441 void TitleWidget::rectChanged() {
442 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
443 if (l.size() == 1 && (l[0])->type() == 3 && !settingUp) {
444 QGraphicsRectItem *rec = (QGraphicsRectItem*)l[0];
445 QColor f = rectFColor->color();
446 f.setAlpha(rectFAlpha->value());
448 penf.setWidth(rectLineWidth->value());
450 QColor b = rectBColor->color();
451 b.setAlpha(rectBAlpha->value());
452 rec->setBrush(QBrush(b));
456 void TitleWidget::fontBold() {
457 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
458 if (l.size() == 1 && (l[0])->type() == 8 && !l[0]->hasFocus()) {
459 //ktextedit->document()->setTextOption();
463 void TitleWidget::svgSelected(const KUrl& u) {
464 QGraphicsSvgItem *svg = new QGraphicsSvgItem(u.toLocalFile());
465 svg->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
466 graphicsView->scene()->addItem(svg);
469 void TitleWidget::itemScaled(int val) {
470 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
472 Transform x = transformations[l[0]];
473 x.scalex = (double)val / 100.0;
474 x.scaley = (double)val / 100.0;
476 qtrans.scale(x.scalex, x.scaley);
477 qtrans.rotate(x.rotate);
478 l[0]->setTransform(qtrans);
479 transformations[l[0]] = x;
483 void TitleWidget::itemRotate(int val) {
484 QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
486 Transform x = transformations[l[0]];
487 x.rotate = (double)val;
489 qtrans.scale(x.scalex, x.scaley);
490 qtrans.rotate(x.rotate);
491 l[0]->setTransform(qtrans);
492 transformations[l[0]] = x;
497 void TitleWidget::setupViewports() {
498 double aspect_ratio = 4.0 / 3.0;//read from project
500 QRectF sp(0, 0, 0, 0);
501 QRectF ep(0, 0, 0, 0);
503 double sv_size = startViewportSize->value();
504 double ev_size = endViewportSize->value();
505 sp.adjust(-sv_size, -sv_size / aspect_ratio, sv_size, sv_size / aspect_ratio);
506 ep.adjust(-ev_size, -ev_size / aspect_ratio, ev_size, ev_size / aspect_ratio);
508 startViewport->setPos(startViewportX->value(), startViewportY->value());
509 endViewport->setPos(endViewportX->value(), endViewportY->value());
511 startViewport->setPolygon(QPolygonF(sp));
512 endViewport->setPolygon(QPolygonF(ep));
516 void TitleWidget::loadTitle() {
517 KUrl url = KFileDialog::getOpenUrl(KUrl(), "*.kdenlivetitle", this, tr("Save Title"));
518 if (!url.isEmpty()) {
519 QList<QGraphicsItem *> items = m_scene->items();
520 for (int i = 0; i < items.size(); i++) {
521 if (items.at(i)->zValue() > -1000) delete items.at(i);
523 m_count = m_titledocument.loadDocument(url, startViewport, endViewport) + 1;
528 void TitleWidget::saveTitle() {
529 KUrl url = KFileDialog::getSaveUrl(KUrl(), "*.kdenlivetitle", this, tr("Save Title"));
530 m_titledocument.saveDocument(url, startViewport, endViewport);
533 QPixmap TitleWidget::renderedPixmap() {
534 QPixmap pix(m_frameWidth, m_frameHeight);
535 pix.fill(Qt::transparent);
536 QPainter painter(&pix);
538 m_scene->clearSelection();
539 QPen framepen = m_frameBorder->pen();
540 m_frameBorder->setPen(Qt::NoPen);
541 QPen startpen = startViewport->pen();
542 QPen endpen = endViewport->pen();
543 startViewport->setPen(Qt::NoPen);
544 endViewport->setPen(Qt::NoPen);
545 if (m_frameImage) delete m_frameImage;
547 m_scene->render(&painter, QRectF(), QRectF(0, 0, m_frameWidth, m_frameHeight));
548 m_frameBorder->setPen(framepen);
549 startViewport->setPen(startpen);
550 endViewport->setPen(endpen);
551 displayBackgroundFrame();
555 #include "moc_titlewidget.cpp"