void UBGraphicsGroupContainerItem::addToGroup(QGraphicsItem *item)
{
    if (!item) {
        qWarning("UBGraphicsGroupContainerItem::addToGroup: cannot add null item");
        return;
    }
    if (item == this) {
        qWarning("UBGraphicsGroupContainerItem::addToGroup: cannot add a group to itself");
        return;
    }

    // COMBINE
    bool ok;
    QTransform itemTransform = item->itemTransform(this, &ok);

    if (!ok) {
        qWarning("UBGraphicsGroupContainerItem::addToGroup: could not find a valid transformation from item to group coordinates");
        return;
    }

    //setting item flags to given item
    item->setSelected(false);
    item->setFlag(QGraphicsItem::ItemIsSelectable, false);
    item->setFlag( QGraphicsItem::ItemIsMovable, false);
    item->setFlag(QGraphicsItem::ItemIsFocusable, true);

    QTransform newItemTransform(itemTransform);
    item->setPos(mapFromItem(item, 0, 0));
    item->setParentItem(this);

    // removing position from translation component of the new transform
    if (!item->pos().isNull())
        newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());

    // removing additional transformations properties applied with itemTransform()
    QPointF origin = item->transformOriginPoint();
    QMatrix4x4 m;
    QList<QGraphicsTransform*> transformList = item->transformations();
    for (int i = 0; i < transformList.size(); ++i)
        transformList.at(i)->applyTo(&m);
    newItemTransform *= m.toTransform().inverted();
    newItemTransform.translate(origin.x(), origin.y());
    newItemTransform.rotate(-item->rotation());
    newItemTransform.scale(1/item->scale(), 1/item->scale());
    newItemTransform.translate(-origin.x(), -origin.y());

    // ### Expensive, we could maybe use dirtySceneTransform bit for optimization

    item->setTransform(newItemTransform);
//    item->d_func()->setIsMemberOfGroup(true);
    prepareGeometryChange();
    itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
    update();
}
KisPerspectiveTransformWorker::KisPerspectiveTransformWorker(KisPaintDeviceSP dev, QPointF center, double aX, double aY, double distance, KoUpdaterPtr progress)
        : m_dev(dev), m_progressUpdater(progress)

{
    QMatrix4x4 m;
    m.rotate(180. * aX / M_PI, QVector3D(1, 0, 0));
    m.rotate(180. * aY / M_PI, QVector3D(0, 1, 0));

    QTransform project = m.toTransform(distance);
    QTransform t = QTransform::fromTranslate(center.x(), center.y());

    QTransform forwardTransform = t.inverted() * project * t;

    init(forwardTransform);
}
void UBGraphicsGroupContainerItem::removeFromGroup(QGraphicsItem *item)
{
    if (!item) {
        qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
        return;
    }

    QGraphicsItem *newParent = parentItem();

    // COMBINE
    bool ok;
    QTransform itemTransform;
    if (newParent)
        itemTransform = item->itemTransform(newParent, &ok);
    else
        itemTransform = item->sceneTransform();

    QPointF oldPos = item->mapToItem(newParent, 0, 0);
    item->setParentItem(newParent);
    item->setPos(oldPos);

    // removing position from translation component of the new transform
    if (!item->pos().isNull())
        itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());

    // removing additional transformations properties applied
    // with itemTransform() or sceneTransform()
    QPointF origin = item->transformOriginPoint();
    QMatrix4x4 m;
    QList<QGraphicsTransform*> transformList = item->transformations();
    for (int i = 0; i < transformList.size(); ++i)
        transformList.at(i)->applyTo(&m);
    itemTransform *= m.toTransform().inverted();
    itemTransform.translate(origin.x(), origin.y());
    itemTransform.rotate(-item->rotation());
    itemTransform.scale(1 / item->scale(), 1 / item->scale());
    itemTransform.translate(-origin.x(), -origin.y());

    // ### Expensive, we could maybe use dirtySceneTransform bit for optimization

    item->setTransform(itemTransform);
//    item->d_func()->setIsMemberOfGroup(item->group() != 0);

    // ### Quite expensive. But removeFromGroup() isn't called very often.
    prepareGeometryChange();
    itemsBoundingRect = childrenBoundingRect();
}
void FadePedal::paintEvent(QPaintEvent* /*event*/)
{
	float lastValue = (m_Ticks.empty() ? 0 : m_Ticks.back().value);
	float angle = (35 * lastValue);

	QRectF r( rect() );
	r.adjust(1, 1, -1, -1);
	
	QPainter painter;
	m_Canvas.fill(0);
	if( painter.begin(&m_Canvas) )
	{
		painter.setRenderHints(QPainter::Antialiasing);
	
		float brightness = m_Click;
		if(m_Hover > 0)
			brightness += (m_Hover*0.2f);

		if( !m_Image.isNull() )
		{
			painter.setOpacity(1.0-(brightness*0.5));
			painter.drawPixmap(	r.x() + qRound((r.width()-m_Image.width())*0.5),
								r.y() + qRound((r.height()-m_Image.height())*0.5),
								m_Image );
			painter.setOpacity(1.0);
		}
	
		QColor brushColor( palette().color(QPalette::Button) );
		if(m_Hover > 0)
		{
			qreal t = (brightness * BUTTON_BRIGHTESS);
			brushColor.setRedF( qMin(brushColor.redF()+t,1.0) );
			brushColor.setGreenF( qMin(brushColor.greenF()+t,1.0) );
			brushColor.setBlueF( qMin(brushColor.blueF()+t,1.0) );
		}
		
		QColor lineColor(brushColor);
		Utils::MakeContrastingColor(1.0f, lineColor);
	
		if( !m_Image.isNull() )
		{
			QPainterPath clip;
			clip.addRoundedRect(r, ROUNDED, ROUNDED);
			painter.setClipPath(clip);

			painter.drawPixmap(	r.x() + qRound((r.width()-m_Image.width())*0.5),
								r.y() + qRound((r.height()-m_Image.height())*0.5),
								m_Image );

			painter.setClipping(false);
		}

		painter.setBrush(brushColor);
		painter.setPen( QPen(lineColor,BORDER) );
		painter.drawRoundedRect(r, ROUNDED, ROUNDED);
	
		if( m_Ticks.empty() )
			m_Points.clear();
		else
			m_Points.resize(m_Ticks.size() + 1);	// end point
	
		if( !m_Points.empty() )
		{
			float lineHeight = (r.height() * 0.8f);
			float lineX = (r.right() + HALF_BORDER);
			float lineY = (r.bottom() - 0.5f*(r.height()-lineHeight));
			float lineWidth = (r.width() + BORDER);
		
			float toPercent = 1.0f/PEDAL_TIMEFRAME;

			for(size_t i=0; i<m_Ticks.size(); i++)
			{
				const sTick &t = m_Ticks[i];
				QPointF &p = m_Points[i];	// end point
			
				float percent = (t.elapsed * toPercent);
				p.setX(lineX - lineWidth*percent);
				p.setY(lineY - lineHeight*t.value);
			}
		
			// end point
			m_Points[m_Points.size()-1] = QPointF(lineX, m_Points[m_Points.size()-2].y());
		
			painter.drawPolyline(m_Points);
		}
	
		if(m_Hover > 0)
		{
			qreal dy = (-m_Hover * BUTTON_RAISE);
			if(dy != 0)
				r.adjust(0, 0, 0, dy);
		}
	
		QColor textColor( palette().color(QPalette::ButtonText) );
		if( !isEnabled() )
			textColor = textColor.darker(150);

		if( !text().isEmpty() )
		{
			if( m_Label.isEmpty() )
			{
				// just text centered
				painter.setFont( font() );
				painter.setPen(textColor);
				painter.drawText(r, Qt::AlignCenter|Qt::TextWordWrap, text());
			}
			else
			{
				// both text and label text
				QRectF textRect;
				painter.setFont( font() );
				painter.setPen(textColor);
				painter.drawText(r, Qt::AlignCenter|Qt::TextWordWrap|Qt::TextDontPrint, text(), &textRect);

				QRectF labelRect;
				painter.drawText(r, Qt::AlignCenter|Qt::TextWordWrap|Qt::TextDontPrint, m_Label, &labelRect);

				qreal h = (r.height() * 0.5 * (textRect.height()/labelRect.height()));
				painter.drawText(QRectF(r.x(),r.y(),r.width(),h), Qt::AlignCenter|Qt::TextWordWrap, text());
				painter.drawText(QRectF(r.x(),r.y()+h,r.width(),r.height()-h), Qt::AlignCenter|Qt::TextWordWrap, m_Label);
			}
		}
		else if( !m_Label.isEmpty() )
		{
			// just label text centered
			painter.setFont( font() );
			painter.setPen(textColor);
			painter.drawText(r, Qt::AlignCenter|Qt::TextWordWrap, m_Label);
		}

		painter.end();
	}

	if( painter.begin(this) )
	{
		if(angle > 0.00001)
		{
			qreal center = (m_Canvas.width() * 0.5);
			QMatrix4x4 matrix;
			matrix.translate(-center, m_Canvas.height());
			matrix.rotate(angle, 1.0, 0, 0);

			painter.translate(center, 0);
			painter.setTransform(matrix.toTransform(300.0), /*combine*/true);
			painter.setRenderHint(QPainter::SmoothPixmapTransform);
			painter.drawImage(0, -m_Canvas.height(), m_Canvas);
		}
		else
			painter.drawImage(0, 0, m_Canvas);

		painter.end();
	}
}