Commit ab622672 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Finalize text shadow in titler (still needs MLT patch)

parent 369bf4b8
......@@ -2855,20 +2855,20 @@ void Bin::showTitleWidget(ProjectClip *clip)
{
QString path = clip->getProducerProperty(QStringLiteral("resource"));
QString titlepath = m_doc->projectFolder().path() + QDir::separator() + "titles/";
QPointer<TitleWidget> dia_ui = new TitleWidget(QUrl(), m_doc->timecode(), titlepath, pCore->monitorManager()->projectMonitor()->render, pCore->window());
connect(dia_ui, SIGNAL(requestBackgroundFrame()), pCore->monitorManager()->projectMonitor(), SLOT(slotGetCurrentImage()));
TitleWidget dia_ui(QUrl(), m_doc->timecode(), titlepath, pCore->monitorManager()->projectMonitor()->render, pCore->window());
connect(&dia_ui, SIGNAL(requestBackgroundFrame()), pCore->monitorManager()->projectMonitor(), SLOT(slotGetCurrentImage()));
QDomDocument doc;
doc.setContent(clip->getProducerProperty(QStringLiteral("xmldata")));
dia_ui->setXml(doc);
if (dia_ui->exec() == QDialog::Accepted) {
dia_ui.setXml(doc);
if (dia_ui.exec() == QDialog::Accepted) {
QMap <QString, QString> newprops;
newprops.insert(QStringLiteral("xmldata"), dia_ui->xml().toString());
if (dia_ui->duration() != clip->duration().frames(m_doc->fps())) {
newprops.insert(QStringLiteral("xmldata"), dia_ui.xml().toString());
if (dia_ui.duration() != clip->duration().frames(m_doc->fps())) {
// duration changed, we need to update duration
newprops.insert(QStringLiteral("out"), QString::number(dia_ui->duration() - 1));
newprops.insert(QStringLiteral("out"), QString::number(dia_ui.duration() - 1));
int currentLength = clip->getProducerIntProperty(QStringLiteral("length"));
if (currentLength <= dia_ui->duration()) {
newprops.insert(QStringLiteral("length"), QString::number(dia_ui->duration()));
if (currentLength <= dia_ui.duration()) {
newprops.insert(QStringLiteral("length"), QString::number(dia_ui.duration()));
} else {
newprops.insert(QStringLiteral("length"), clip->getProducerProperty(QStringLiteral("length")));
}
......@@ -2879,14 +2879,13 @@ void Bin::showTitleWidget(ProjectClip *clip)
// we are editing an external file, asked if we want to detach from that file or save the result to that title file.
if (KMessageBox::questionYesNo(pCore->window(), i18n("You are editing an external title clip (%1). Do you want to save your changes to the title file or save the changes for this project only?", path), i18n("Save Title"), KGuiItem(i18n("Save to title file")), KGuiItem(i18n("Save in project only"))) == KMessageBox::Yes) {
// save to external file
dia_ui->saveTitle(QUrl::fromLocalFile(path));
dia_ui.saveTitle(QUrl::fromLocalFile(path));
} else {
newprops.insert(QStringLiteral("resource"), QString());
}
}
slotEditClipCommand(clip->clipId(), clip->currentProperties(newprops), newprops);
}
delete dia_ui;
}
void Bin::slotResetInfoMessage()
......
......@@ -38,7 +38,9 @@
MyTextItem::MyTextItem(const QString &txt, QGraphicsItem *parent) :
QGraphicsTextItem(txt, parent)
, m_alignment(Qt::AlignLeft)
, m_useShadow(false)
{
setCacheMode(QGraphicsItem::ItemCoordinateCache);
document()->setDocumentMargin(0);
updateGeometry();
connect(document(), SIGNAL(contentsChange(int, int, int)),
......@@ -50,6 +52,29 @@ Qt::Alignment MyTextItem::alignment() const
return m_alignment;
}
void MyTextItem::updateShadow(bool enabled, int blur, int xoffset, int yoffset, QColor color)
{
m_shadowOffset = QPoint(xoffset, yoffset);
m_shadowBlur = blur;
m_shadowColor = color;
m_useShadow = enabled;
updateShadow();
update();
}
QStringList MyTextItem::shadowInfo() const
{
QStringList info;
info << QString::number(m_useShadow) << m_shadowColor.name(QColor::HexArgb) << QString::number( m_shadowBlur) << QString::number(m_shadowOffset.x()) << QString::number(m_shadowOffset.y());
return info;
}
void MyTextItem::loadShadow(QStringList info)
{
if (info.count() < 5) return;
updateShadow((info.at(0).toInt() == true), info.at(2).toInt(), info.at(3).toInt(),info.at(4).toInt(), QColor(info.at(1)));
}
void MyTextItem::setAlignment(Qt::Alignment alignment)
{
m_alignment = alignment;
......@@ -82,6 +107,131 @@ void MyTextItem::updateGeometry(int, int, int)
cursor.setPosition(position); // restore cursor position
setTextCursor(cursor);
}
if (m_useShadow) {
updateShadow();
}
}
void MyTextItem::updateShadow()
{
QString text = toPlainText();
if (text.isEmpty()) {
m_shadow = QImage();
return;
}
QFontMetrics metrics(font());
//ADJUST TO CURRENT SETTING
int lineSpacing = 0;
lineSpacing += metrics.lineSpacing();
QPainterPath path;
// Calculate line width
QStringList lines = text.split('\n');
double linePos = metrics.ascent();
QRectF bounding = boundingRect();
foreach(const QString &line, lines)
{
QPainterPath linePath;
linePath.addText(0, linePos, font(), line);
linePos += lineSpacing;
if ( m_alignment == Qt::AlignHCenter ) {
double offset = (bounding.width() - metrics.width(line)) / 2;
linePath.translate(offset, 0);
} else if ( m_alignment == Qt::AlignRight ) {
double offset = (bounding.width() - metrics.width(line));
linePath.translate(offset, 0);
}
path.addPath(linePath);
}
// Calculate position of text in parent item
QRectF pathRect = QRectF(0, 0, bounding.width(), linePos - lineSpacing + metrics.descent() );
QPointF offset = bounding.center() - pathRect.center() + m_shadowOffset;
path.translate(offset);
QRectF fullSize = bounding.united(path.boundingRect());
QImage shadow(fullSize.width(), fullSize.height(), QImage::Format_ARGB32_Premultiplied);
shadow.fill(Qt::transparent);
QPainter painter(&shadow);
painter.fillPath(path, QBrush(m_shadowColor));
painter.end();
if (m_shadowBlur > 0) {
blurShadow(shadow, m_shadowBlur, true);
} else {
m_shadow = shadow;
}
}
void MyTextItem::blurShadow(const QImage &image, int radius, bool alphaOnly)
{
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
m_shadow = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
int r1 = 0;
int r2 = image.height() - 1;
int c1 = 0;
int c2 = image.width() - 1;
int bpl = m_shadow.bytesPerLine();
int rgba[4];
unsigned char* p;
int i1 = 0;
int i2 = 3;
if (alphaOnly)
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
for (int col = c1; col <= c2; col++) {
p = m_shadow.scanLine(r1) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += bpl;
for (int j = r1; j < r2; j++, p += bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = m_shadow.scanLine(row) + c1 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += 4;
for (int j = c1; j < c2; j++, p += 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int col = c1; col <= c2; col++) {
p = m_shadow.scanLine(r2) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= bpl;
for (int j = r1; j < r2; j++, p -= bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = m_shadow.scanLine(row) + c2 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= 4;
for (int j = c1; j < c2; j++, p -= 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
}
void MyTextItem::paint( QPainter *painter, const QStyleOptionGraphicsItem * option, QWidget* w)
{
if (m_useShadow && !m_shadow.isNull()) {
painter->drawImage(0, 0, m_shadow);
}
QGraphicsTextItem::paint(painter, option, w);
}
void MyTextItem::updateGeometry()
......@@ -110,12 +260,15 @@ QRectF MyTextItem::boundingRect() const
if (lines > 1) {
base.setHeight(lines * lineHeight2 + lineHeight * (lines - 1));
}
base.setRight(base.right() + m_shadowOffset.x());
base.setBottom(base.bottom() + m_shadowOffset.y());
return base;
}
MyRectItem::MyRectItem(QGraphicsItem *parent) :
QGraphicsRectItem(parent)
{
setCacheMode(QGraphicsItem::ItemCoordinateCache);
}
void MyRectItem::setRect(const QRectF & rectangle)
......@@ -337,12 +490,13 @@ void GraphicsSceneRectMove::mousePressEvent(QGraphicsSceneMouseEvent* e)
m_sceneClickPoint = e->scenePos();
m_selectedItem = NULL;
} else if (m_tool == TITLE_TEXT) {
m_selectedItem = new MyTextItem(QString(), NULL);
addItem(m_selectedItem);
emit newText((MyTextItem *) m_selectedItem);
m_selectedItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
((MyTextItem *)m_selectedItem)->setTextInteractionFlags(Qt::TextEditorInteraction);
m_selectedItem->setPos(e->scenePos() - QPointF(0, (int)(m_fontSize / 2)));
MyTextItem *textItem = new MyTextItem(QString(), NULL);
addItem(textItem);
emit newText(textItem);
textItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
textItem->setPos(e->scenePos() - QPointF(0, (int)(m_fontSize / 2)));
m_selectedItem = textItem;
QGraphicsScene::mousePressEvent(e);
}
......
......@@ -31,13 +31,24 @@ class MyTextItem: public QGraphicsTextItem
{
Q_OBJECT
public:
MyTextItem(const QString &, QGraphicsItem *);
MyTextItem(const QString &, QGraphicsItem *parent = Q_NULLPTR);
void setAlignment(Qt::Alignment alignment);
QRectF boundingRect() const;
Qt::Alignment alignment() const;
void updateShadow(bool enabled, int blur, int xoffset, int yoffset, QColor color);
QStringList shadowInfo() const;
void loadShadow(QStringList info);
void paint( QPainter *painter, const QStyleOptionGraphicsItem * option, QWidget* w);
private:
Qt::Alignment m_alignment;
QImage m_shadow;
QPoint m_shadowOffset;
int m_shadowBlur;
QColor m_shadowColor;
bool m_useShadow;
void updateShadow();
void blurShadow(const QImage &image, int radius, bool alphaOnly);
public slots:
void updateGeometry(int, int, int);
......
......@@ -168,6 +168,10 @@ QDomDocument TitleDocument::xml(QGraphicsRectItem* startv, QGraphicsRectItem* en
content.setAttribute(QStringLiteral("pencolor"), colorToString(static_cast<QGraphicsRectItem*>(item)->pen().color()));
content.setAttribute(QStringLiteral("penwidth"), static_cast<QGraphicsRectItem*>(item)->pen().width());
content.setAttribute(QStringLiteral("brushcolor"), colorToString(static_cast<QGraphicsRectItem*>(item)->brush().color()));
gradient = item->data(TitleDocument::Gradient).toString();
if (!gradient.isEmpty()) {
content.setAttribute(QStringLiteral("gradient"), gradient);
}
break;
case 8:
e.setAttribute(QStringLiteral("type"), QStringLiteral("QGraphicsTextItem"));
......@@ -242,6 +246,8 @@ QDomDocument TitleDocument::xml(QGraphicsRectItem* startv, QGraphicsRectItem* en
if (t->textWidth() != -1) {
content.setAttribute(QStringLiteral("alignment"), (int) t->alignment());
}
content.setAttribute(QStringLiteral("shadow"), t->shadowInfo().join(";"));
break;
default:
continue;
......@@ -395,12 +401,13 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
QDomNodeList items = titles.item(0).childNodes();
for (int i = 0; i < items.count(); ++i) {
QGraphicsItem *gitem = NULL;
QDomNode itemNode = items.item(i);
//qDebug() << items.item(i).attributes().namedItem("type").nodeValue();
int zValue = items.item(i).attributes().namedItem(QStringLiteral("z-index")).nodeValue().toInt();
double xPosition = items.item(i).namedItem(QStringLiteral("position")).attributes().namedItem(QStringLiteral("x")).nodeValue().toDouble();
int zValue = itemNode.attributes().namedItem(QStringLiteral("z-index")).nodeValue().toInt();
double xPosition = itemNode.namedItem(QStringLiteral("position")).attributes().namedItem(QStringLiteral("x")).nodeValue().toDouble();
if (zValue > -1000) {
if (items.item(i).attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsTextItem")) {
QDomNamedNodeMap txtProperties = items.item(i).namedItem(QStringLiteral("content")).attributes();
if (itemNode.attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsTextItem")) {
QDomNamedNodeMap txtProperties = itemNode.namedItem(QStringLiteral("content")).attributes();
QFont font(txtProperties.namedItem(QStringLiteral("font")).nodeValue());
QDomNode node = txtProperties.namedItem(QStringLiteral("font-bold"));
......@@ -425,10 +432,10 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
}
font.setLetterSpacing(QFont::AbsoluteSpacing, txtProperties.namedItem(QStringLiteral("letter-spacing")).nodeValue().toInt());
QColor col(stringToColor(txtProperties.namedItem(QStringLiteral("font-color")).nodeValue()));
MyTextItem *txt = new MyTextItem(items.item(i).namedItem(QStringLiteral("content")).firstChild().nodeValue(), NULL);
MyTextItem *txt = new MyTextItem(itemNode.namedItem(QStringLiteral("content")).firstChild().nodeValue(), NULL);
m_scene->addItem(txt);
txt->setFont(font);
txt->setTextInteractionFlags(Qt::NoTextInteraction);
m_scene->addItem(txt);
QTextCursor cursor(txt->document());
cursor.select(QTextCursor::Document);
QTextCharFormat cformat = cursor.charFormat();
......@@ -469,6 +476,11 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
txt->setData(OriginYTop, txtProperties.namedItem(QStringLiteral("kdenlive-axis-y-inverted")).nodeValue().toInt());
}
if (!txtProperties.namedItem(QStringLiteral("shadow")).isNull()) {
QString info = txtProperties.namedItem(QStringLiteral("shadow")).nodeValue();
txt->loadShadow(info.split(';'));
}
// Effects
if (!txtProperties.namedItem(QStringLiteral("typewriter")).isNull()) {
QStringList effData = QStringList() << QStringLiteral("typewriter") << txtProperties.namedItem(QStringLiteral("typewriter")).nodeValue();
......@@ -490,16 +502,29 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
}
gitem = txt;
} else if (items.item(i).attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsRectItem")) {
QString rect = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("rect")).nodeValue();
QString br_str = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("brushcolor")).nodeValue();
QString pen_str = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("pencolor")).nodeValue();
double penwidth = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("penwidth")).nodeValue().toDouble();
QGraphicsRectItem *rec = m_scene->addRect(stringToRect(rect), QPen(QBrush(stringToColor(pen_str)), penwidth, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin), QBrush(stringToColor(br_str)));
} else if (itemNode.attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsRectItem")) {
QString rect = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("rect")).nodeValue();
QString br_str = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("brushcolor")).nodeValue();
QString pen_str = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("pencolor")).nodeValue();
double penwidth = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("penwidth")).nodeValue().toDouble();
MyRectItem *rec = new MyRectItem();
rec->setRect(stringToRect(rect));
rec->setPen(QPen(QBrush(stringToColor(pen_str)), penwidth, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin));
if (itemNode.namedItem(QStringLiteral("gradient")).isNull() == false) {
// Gradient color
QString data = itemNode.namedItem(QStringLiteral("gradient")).nodeValue();
rec->setData(TitleDocument::Gradient, data);
QLinearGradient gr = GradientWidget::gradientFromString(data, rec->rect().width(), rec->rect().height());
rec->setBrush(QBrush(gr));
} else {
rec->setBrush(QBrush(stringToColor(br_str)));
}
m_scene->addItem(rec);
gitem = rec;
} else if (items.item(i).attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsPixmapItem")) {
QString url = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("url")).nodeValue();
QString base64 = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("base64")).nodeValue();
} else if (itemNode.attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsPixmapItem")) {
QString url = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("url")).nodeValue();
QString base64 = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("base64")).nodeValue();
QPixmap pix;
if (base64.isEmpty()) {
pix.load(url);
......@@ -513,9 +538,9 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
rec->setData(Qt::UserRole + 1, base64);
}
gitem = rec;
} else if (items.item(i).attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsSvgItem")) {
QString url = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("url")).nodeValue();
QString base64 = items.item(i).namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("base64")).nodeValue();
} else if (itemNode.attributes().namedItem(QStringLiteral("type")).nodeValue() == QLatin1String("QGraphicsSvgItem")) {
QString url = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("url")).nodeValue();
QString base64 = itemNode.namedItem(QStringLiteral("content")).attributes().namedItem(QStringLiteral("base64")).nodeValue();
QGraphicsSvgItem *rec = NULL;
if (base64.isEmpty()) {
rec = new QGraphicsSvgItem(url);
......@@ -539,21 +564,21 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
//pos and transform
if (gitem) {
QPointF p(xPosition,
items.item(i).namedItem(QStringLiteral("position")).attributes().namedItem(QStringLiteral("y")).nodeValue().toDouble());
itemNode.namedItem(QStringLiteral("position")).attributes().namedItem(QStringLiteral("y")).nodeValue().toDouble());
gitem->setPos(p);
QDomElement trans = items.item(i).namedItem(QStringLiteral("position")).firstChild().toElement();
QDomElement trans = itemNode.namedItem(QStringLiteral("position")).firstChild().toElement();
gitem->setTransform(stringToTransform(trans.firstChild().nodeValue()));
QString rotate = trans.attribute(QStringLiteral("rotation"));
if (!rotate.isEmpty()) gitem->setData(TitleDocument::RotateFactor, stringToList(rotate));
QString zoom = trans.attribute(QStringLiteral("zoom"));
if (!zoom.isEmpty()) gitem->setData(TitleDocument::ZoomFactor, zoom.toInt());
int zValue = items.item(i).attributes().namedItem(QStringLiteral("z-index")).nodeValue().toInt();
int zValue = itemNode.attributes().namedItem(QStringLiteral("z-index")).nodeValue().toInt();
if (zValue > maxZValue) maxZValue = zValue;
gitem->setZValue(zValue);
gitem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
// effects
QDomNode eff = items.item(i).namedItem(QStringLiteral("effect"));
QDomNode eff = itemNode.namedItem(QStringLiteral("effect"));
if (!eff.isNull()) {
QDomElement e = eff.toElement();
if (e.attribute(QStringLiteral("type")) == QLatin1String("blur")) {
......@@ -569,10 +594,10 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
}
}
if (items.item(i).nodeName() == QLatin1String("background")) {
if (itemNode.nodeName() == QLatin1String("background")) {
//qDebug() << items.item(i).attributes().namedItem("color").nodeValue();
QColor color = QColor(stringToColor(items.item(i).attributes().namedItem(QStringLiteral("color")).nodeValue()));
//color.setAlpha(items.item(i).attributes().namedItem("alpha").nodeValue().toInt());
QColor color = QColor(stringToColor(itemNode.attributes().namedItem(QStringLiteral("color")).nodeValue()));
//color.setAlpha(itemNode.attributes().namedItem("alpha").nodeValue().toInt());
QList<QGraphicsItem *> items = m_scene->items();
for (int i = 0; i < items.size(); ++i) {
if (items.at(i)->zValue() == -1100) {
......@@ -580,13 +605,13 @@ int TitleDocument::loadFromXml(const QDomDocument& doc, QGraphicsRectItem* start
break;
}
}
} else if (items.item(i).nodeName() == QLatin1String("startviewport") && startv) {
QString rect = items.item(i).attributes().namedItem(QStringLiteral("rect")).nodeValue();
} else if (itemNode.nodeName() == QLatin1String("startviewport") && startv) {
QString rect = itemNode.attributes().namedItem(QStringLiteral("rect")).nodeValue();
QRectF r = stringToRect(rect);
startv->setRect(0, 0, r.width(), r.height());
startv->setPos(r.topLeft());
} else if (items.item(i).nodeName() == QLatin1String("endviewport") && endv) {
QString rect = items.item(i).attributes().namedItem(QStringLiteral("rect")).nodeValue();
} else if (itemNode.nodeName() == QLatin1String("endviewport") && endv) {
QString rect = itemNode.attributes().namedItem(QStringLiteral("rect")).nodeValue();
QRectF r = stringToRect(rect);
endv->setRect(0, 0, r.width(), r.height());
endv->setPos(r.topLeft());
......
......@@ -87,6 +87,7 @@ TitleWidget::TitleWidget(const QUrl &url, const Timecode &tc, const QString &pro
rectFColor->setAlphaChannelEnabled(true);
fontColorButton->setAlphaChannelEnabled(true);
textOutlineColor->setAlphaChannelEnabled(true);
shadowColor->setAlphaChannelEnabled(true);
QButtonGroup *colorGroup = new QButtonGroup(this);
colorGroup->addButton(gradient_color);
......@@ -147,6 +148,12 @@ TitleWidget::TitleWidget(const QUrl &url, const Timecode &tc, const QString &pro
connect(backgroundColor, SIGNAL(changed(QColor)), this, SLOT(slotChangeBackground())) ;
connect(backgroundAlpha, SIGNAL(valueChanged(int)), this, SLOT(slotChangeBackground())) ;
connect(shadowBox, SIGNAL(toggled(bool)), this, SLOT(slotUpdateShadow()));
connect(shadowColor, SIGNAL(changed(QColor)), this, SLOT(slotUpdateShadow()));
connect(blur_radius, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateShadow()));
connect(shadowX, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateShadow()));
connect(shadowY, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateShadow()));
connect(fontColorButton, SIGNAL(changed(QColor)), this, SLOT(slotUpdateText()));
connect(plain_color, SIGNAL(clicked(bool)), this, SLOT(slotUpdateText()));
connect(gradient_color, SIGNAL(clicked(bool)), this, SLOT(slotUpdateText()));
......@@ -496,6 +503,7 @@ TitleWidget::TitleWidget(const QUrl &url, const Timecode &tc, const QString &pro
TitleWidget::~TitleWidget()
{
m_scene->blockSignals(true);
delete m_buttonRect;
delete m_buttonText;
delete m_buttonImage;
......@@ -924,7 +932,7 @@ void TitleWidget::slotNewText(MyTextItem *tt)
tt->setData(TitleDocument::OutlineWidth, outlineWidth);
tt->setData(TitleDocument::OutlineColor, outlineColor);
if (outlineWidth > 0.0) cformat.setTextOutline(QPen(outlineColor, outlineWidth));
tt->updateShadow(shadowBox->isChecked(), blur_radius->value(), shadowX->value(), shadowY->value(), shadowColor->color());
if (gradient_color->isChecked()) {
QString gradientData = gradients_combo->currentData().toString();
tt->setData(TitleDocument::Gradient, gradientData);
......@@ -1552,9 +1560,9 @@ void TitleWidget::slotUpdateText()
double outlineWidth = textOutline->value() / 10.0;
int i;
for (i = 0; i < graphicsView->scene()->selectedItems().length(); ++i) {
QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
for (i = 0; i < l.length(); ++i) {
MyTextItem* item = NULL;
QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
if (l.at(i)->type() == TEXTITEM) {
item = static_cast <MyTextItem *>(l.at(i));
}
......@@ -2198,7 +2206,6 @@ void TitleWidget::slotAddEffect(int ix)
}
} else // Hide the effects stack when more than one element is selected.
effect_stack->setHidden(true);
*/
foreach(QGraphicsItem * item, list) {
switch (effect) {
case NOEFFECT:
......@@ -2206,10 +2213,6 @@ void TitleWidget::slotAddEffect(int ix)
item->setGraphicsEffect(0);
break;
case TYPEWRITEREFFECT:
/*
* Allow the user to set the typewriter effect to more than one
* element, but do not add it to non-text elements.
*/
if (item->type() == TEXTITEM) {
QStringList effdata = QStringList() << QStringLiteral("typewriter") << QString::number(typewriter_delay->value()) + ';' + QString::number(typewriter_start->value());
item->setData(100, effdata);
......@@ -2223,7 +2226,7 @@ void TitleWidget::slotAddEffect(int ix)
item->setGraphicsEffect(new QGraphicsDropShadowEffect());
break;
}
}
}*/
}
void TitleWidget::slotFontText(const QString& s)
......@@ -2594,14 +2597,25 @@ void TitleWidget::prepareTools(QGraphicsItem *referenceItem)
} else {
plain_color->setChecked(true);
}
QTextCursor cur = i->textCursor();
QTextBlockFormat format = cur.blockFormat();
if (format.alignment() == Qt::AlignHCenter) buttonAlignCenter->setChecked(true);
else if (format.alignment() == Qt::AlignRight) buttonAlignRight->setChecked(true);
if (i->alignment() == Qt::AlignHCenter) buttonAlignCenter->setChecked(true);
else if (i->alignment() == Qt::AlignRight) buttonAlignRight->setChecked(true);
else buttonAlignLeft->setChecked(true);
QStringList sInfo = i->shadowInfo();
if (sInfo.count() >= 5) {
shadowBox->setChecked(sInfo.at(0).toInt() == true);
shadowBox->blockSignals(true);
shadowColor->setColor(QColor(sInfo.at(1)));
blur_radius->setValue(sInfo.at(2).toInt());
shadowX->setValue(sInfo.at(3).toInt());
shadowY->setValue(sInfo.at(4).toInt());
shadowBox->blockSignals(false);
}
letter_spacing->blockSignals(true);
line_spacing->blockSignals(true);
QTextCursor cur = i->textCursor();
QTextBlockFormat format = cur.blockFormat();
letter_spacing->setValue(font.letterSpacing());
line_spacing->setValue(format.lineHeight());
letter_spacing->blockSignals(false);
......@@ -2788,4 +2802,18 @@ void TitleWidget::loadGradients()
gradients_rect_combo->blockSignals(false);
}
void TitleWidget::slotUpdateShadow()
{
QList<QGraphicsItem*> l = graphicsView->scene()->selectedItems();
for (int i = 0; i < graphicsView->scene()->selectedItems().length(); ++i) {
MyTextItem* item = NULL;
if (l.at(i)->type() == TEXTITEM) {
item = static_cast <MyTextItem *>(l.at(i));
}
if (!item) {
// No text item, try next one.
continue;
}