Subversion Repositories Scribus

Rev

Rev 16957 | Rev 17181 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/


#include "propertywidget_group.h"
#include "propertywidget_groupshape.h"
#include "transparencypalette.h"
#include "scribus.h"
#include "scribusdoc.h"
#include "selection.h"
#include "util_math.h"

PropertyWidget_Group::PropertyWidget_Group( QWidget* parent) : QFrame(parent)
{
        m_item = 0;
        m_ScMW = 0;
        m_unitIndex = 0;
        m_unitRatio = 1.0;

        setSizePolicy( QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));

        QVBoxLayout* vboxLayout = new QVBoxLayout();
        vboxLayout->setMargin(5);
        vboxLayout->setSpacing(1);
        vboxLayout->setAlignment(Qt::AlignTop);

        this->setLayout(vboxLayout);
        this->setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum));
       
        groupShapeWidget = new PropertyWidget_GroupShape(this);
        vboxLayout->addWidget(groupShapeWidget);

        QVBoxLayout* tboxLayout = new QVBoxLayout();
        tboxLayout->setMargin(0);
        tboxLayout->setSpacing(1);
        tboxLayout->setAlignment(Qt::AlignTop);

        transGroupBox = new QGroupBox(this);
        transGroupBox->setLayout(tboxLayout);
        transGroupBox->setTitle( tr("Transparency") );
        transGroupBox->setFlat(true);

        groupTransWidget = new Tpalette(transGroupBox);
        groupTransWidget->hideSelectionButtons();
        tboxLayout->addWidget(groupTransWidget);

        vboxLayout->addWidget(transGroupBox);

        languageChange();
}

void PropertyWidget_Group::setMainWindow(ScribusMainWindow *mw)
{
        m_ScMW = mw;

        groupShapeWidget->setMainWindow(mw);

        connect(m_ScMW, SIGNAL(UpdateRequest(int)), this  , SLOT(handleUpdateRequest(int)));
}

void PropertyWidget_Group::setDoc(ScribusDoc *d)
{
        if((d == (ScribusDoc*) m_doc) || (m_ScMW && m_ScMW->scriptIsRunning()))
                return;

        if (m_doc)
        {
                disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
                disconnect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
        }

        m_doc  = d;
        m_item = NULL;

        groupShapeWidget->setDoc(m_doc);

        groupTransWidget->setDocument(m_doc);
        groupTransWidget->setCurrentItem(NULL);

        if (m_doc.isNull())
        {
                disconnectSignals();
                return;
        }

        m_unitRatio = m_doc->unitRatio();
        m_unitIndex = m_doc->unitIndex();

        connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
        connect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
}

void PropertyWidget_Group::setCurrentItem(PageItem *item)
{
        if (!m_ScMW || m_ScMW->scriptIsRunning())
                return;
        //CB We shouldnt really need to process this if our item is the same one
        //maybe we do if the item has been changed by scripter.. but that should probably
        //set some status if so.
        //FIXME: This wont work until when a canvas deselect happens, m_item must be NULL.
        //if (m_item == i)
        //      return;

        if (item && m_doc.isNull())
                setDoc(item->doc());

        m_item = item;

        disconnectSignals();
        enableFromSelection();

        if (m_item)
        {
                connectSignals();
        }
}

void PropertyWidget_Group::connectSignals()
{
        connect(groupTransWidget, SIGNAL(gradientChanged())  , this, SLOT(handleGradientChanged()));

        connect(groupTransWidget, SIGNAL(NewTrans(double))   , this, SLOT(handleGroupTransparency(double)));
        connect(groupTransWidget, SIGNAL(NewBlend(int))      , this, SLOT(handleGroupBlending(int)));
        connect(groupTransWidget, SIGNAL(NewGradient(int))   , this, SLOT(handleGroupGradMask(int)));
        connect(groupTransWidget, SIGNAL(NewPattern(QString)), this, SLOT(handleGroupPatternMask(QString)));
        connect(groupTransWidget, SIGNAL(NewPatternProps(double, double, double, double, double, double, double, bool, bool)), this, SLOT(handleGroupPatternMaskProps(double, double, double, double, double, double, double, bool, bool)));

        connect(groupTransWidget, SIGNAL(editGradient())     , this, SLOT(handleGradientEdit()));
        connect(groupTransWidget, SIGNAL(NewSpecial(double, double, double, double, double, double, double, double, double, double)), this, SLOT(handleSpecialGradient(double, double, double, double, double, double, double, double )));
}

void PropertyWidget_Group::disconnectSignals()
{
        disconnect(groupTransWidget, SIGNAL(gradientChanged())  , this, SLOT(handleGradientChanged()));

        disconnect(groupTransWidget, SIGNAL(NewTrans(double))   , this, SLOT(handleGroupTransparency(double)));
        disconnect(groupTransWidget, SIGNAL(NewBlend(int))      , this, SLOT(handleGroupBlending(int)));
        disconnect(groupTransWidget, SIGNAL(NewGradient(int))   , this, SLOT(handleGroupGradMask(int)));
        disconnect(groupTransWidget, SIGNAL(NewPattern(QString)), this, SLOT(handleGroupPatternMask(QString)));
        disconnect(groupTransWidget, SIGNAL(NewPatternProps(double, double, double, double, double, double, double, bool, bool)), this, SLOT(handleGroupPatternMaskProps(double, double, double, double, double, double, double, bool, bool)));

        disconnect(groupTransWidget, SIGNAL(editGradient())     , this, SLOT(handleGradientEdit()));
        disconnect(groupTransWidget, SIGNAL(NewSpecial(double, double, double, double, double, double, double, double, double, double)), this, SLOT(handleSpecialGradient(double, double, double, double, double, double, double, double )));
}

void PropertyWidget_Group::enableFromSelection(void)
{
        bool widgetEnabled = false;
        if (m_item && m_doc)
        {
                if (m_doc->m_Selection->count() > 1)
                {
                        if ((m_item->isGroup()) && (!m_item->isSingleSel))
                                widgetEnabled = true;
                }
                else if (m_doc->m_Selection->count() == 1)
                {
                        widgetEnabled = m_item->isSymbol() || m_item->isGroup();
                }
        }
        setEnabled(widgetEnabled);
}

void PropertyWidget_Group::handleSelectionChanged()
{
        if (!m_doc || !m_ScMW || m_ScMW->scriptIsRunning())
                return;

        PageItem* currItem = currentItemFromSelection();
        setCurrentItem(currItem);
        updateGeometry();
        repaint();
}

void PropertyWidget_Group::handleUpdateRequest(int updateFlags)
{
        // Nothing to do, all is handled by subwidgets
}

void PropertyWidget_Group::handleGradientChanged()
{
        if (m_doc)
        {
                VGradient vg(groupTransWidget->gradEdit->gradient());
                m_doc->itemSelection_SetMaskGradient(vg);
        }
}

void PropertyWidget_Group::handleGroupTransparency(double trans)
{
        if (m_item)
        {
                m_item->setFillTransparency(trans);
                m_item->update();
                m_ScMW->slotDocCh();
        }
}

void PropertyWidget_Group::handleGroupBlending(int blend)
{
        if (m_item)
        {
                m_item->setFillBlendmode(blend);
                m_item->update();
                m_ScMW->slotDocCh();
        }
}

void PropertyWidget_Group::handleGroupGradMask(int typ)
{
        if (m_item)
        {
                m_item->GrMask = typ;
                if ((typ > 0) && (typ < 7))
                        m_item->updateGradientVectors();
                m_item->update();
                m_ScMW->slotDocCh();
        }
}

void PropertyWidget_Group::handleGroupPatternMask(QString pattern)
{
        if (m_item)
        {
                m_item->setPatternMask(pattern);
                m_item->update();
                m_ScMW->slotDocCh();
        }
}

void PropertyWidget_Group::handleGroupPatternMaskProps(double imageScaleX, double imageScaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
{
        if (m_item)
        {
                m_item->setMaskTransform(imageScaleX, imageScaleY, offsetX, offsetY, rotation, skewX, skewY);
                m_item->setMaskFlip(mirrorX, mirrorY);
                m_item->update();
                m_ScMW->slotDocCh();
        }
}

void PropertyWidget_Group::handleGradientEdit()
{
        if (!m_ScMW || m_ScMW->scriptIsRunning())
                return;
        if (m_doc && m_item)
        {
                m_ScMW->view->editStrokeGradient = 2;
                if (groupTransWidget->gradEditButton->isChecked())
                        m_ScMW->view->requestMode(modeEditGradientVectors);
                else
                        m_ScMW->view->requestMode(modeNormal);
        }
}

void PropertyWidget_Group::handleSpecialGradient(double x1, double y1, double x2, double y2, double fx, double fy, double sg, double sk)
{
        if (!m_ScMW || m_ScMW->scriptIsRunning())
                return;
        if (m_doc && m_item)
        {
                QRectF upRect;
                m_item->GrMaskStartX = x1 / m_unitRatio;
                m_item->GrMaskStartY = y1 / m_unitRatio;
                m_item->GrMaskEndX = x2 / m_unitRatio;
                m_item->GrMaskEndY = y2 / m_unitRatio;
                m_item->GrMaskFocalX = fx / m_unitRatio;
                m_item->GrMaskFocalY = fy / m_unitRatio;
                m_item->GrMaskScale = sg;
                m_item->GrMaskSkew = sk;
                if ((m_item->GrMask == 1) || (m_item->GrMask == 4))
                {
                        m_item->GrMaskFocalX = m_item->GrMaskStartX;
                        m_item->GrMaskFocalY = m_item->GrMaskStartY;
                }
                m_item->update();
                upRect = QRectF(QPointF(m_item->GrMaskStartX, m_item->GrMaskStartY), QPointF(m_item->GrMaskEndX, m_item->GrMaskEndY));
                double radEnd = distance(m_item->GrMaskEndX - m_item->GrMaskStartX, m_item->GrMaskEndY - m_item->GrMaskStartY);
                double rotEnd = xy2Deg(m_item->GrMaskEndX - m_item->GrMaskStartX, m_item->GrMaskEndY - m_item->GrMaskStartY);
                QTransform m;
                m.translate(m_item->GrMaskStartX, m_item->GrMaskStartY);
                m.rotate(rotEnd);
                m.rotate(-90);
                m.rotate(m_item->GrMaskSkew);
                m.translate(radEnd * m_item->GrMaskScale, 0);
                QPointF shP = m.map(QPointF(0,0));
                upRect |= QRectF(shP, QPointF(m_item->GrMaskEndX, m_item->GrMaskEndY)).normalized();
                upRect |= QRectF(shP, QPointF(m_item->GrMaskStartX, m_item->GrMaskStartY)).normalized();
                upRect |= QRectF(shP, QPointF(0, 0)).normalized();
                upRect |= QRectF(shP, QPointF(m_item->width(), m_item->height())).normalized();
                upRect.translate(m_item->xPos(), m_item->yPos());
                m_doc->regionsChanged()->update(upRect.adjusted(-10.0, -10.0, 10.0, 10.0));
                m_ScMW->slotDocCh();
        }
}

void PropertyWidget_Group::changeEvent(QEvent *e)
{
        if (e->type() == QEvent::LanguageChange)
        {
                languageChange();
                return;
        }
        QFrame::changeEvent(e);
}

void PropertyWidget_Group::languageChange()
{
        transGroupBox->setTitle( tr("Transparency") );
}

void PropertyWidget_Group::unitChange()
{
        if (!m_doc)
                return;

        double oldRatio = m_unitRatio;
        m_unitRatio = m_doc->unitRatio();
        m_unitIndex = m_doc->unitIndex();

        groupTransWidget->blockSignals(true);
        groupTransWidget->unitChange(oldRatio, m_unitRatio, m_doc->unitIndex());
        groupTransWidget->blockSignals(false);
}