Making the sheet displaying QGraphicsItem CanvasItem of Calligra transparent on a GraphicsScene

Philip Van Hoof philip at codeminded.be
Mon Dec 3 09:49:19 GMT 2012


Hi Boudewijn Rempt,

I think my solution will be useful for future users of Calligra's
components. This is what I came up with, and this is working as
expected: cells that had no background info set become transparent,
cells that have background info set retain that background as
non-transparent (this is my expected result). I guess opacity setting
could still be used (while painting or globally) in case somebody wants
cells with background info set to be semi-transparent (but for my
use-case this isn't the case). I would o could have decorated painter
instead of writing to the original, and then passing my decorated one to
super's method, but it looks like QPainter has no copy constructor. And
I think that if I just restore painter that it'll all be fine too.

My solution:


myfile.h

class MyGraphicsItem: public QGraphicsRectItem
{
  public:
    explicit MyGraphicsItem( const QFileInfo& file, const QRectF& rect, QGraphicsItem *parent = 0) ;
    ~MyGraphicsItem();

    /*reimp*/ void resize(const QSizeF& size);

    void updateFile(const QFileInfo& file);

    enum ScaleMode {
      ScaleToItem = 0, //scale to the item's size
//    AspectRatioScale, //same, keep aspect ratio
      NoScale
    };

private:
    bool m_canvasSet;
    Calligra::Sheets::Doc *m_cachedDoc;
    Calligra::Sheets::CanvasItem *m_canvas;
    Calligra::Sheets::Part *m_part;
    MyGraphicsItem::ScaleMode m_scaleMode;
};

class TransparentCanvasItem : public Calligra::Sheets::CanvasItem
{
    Q_OBJECT

public:

    TransparentCanvasItem(Calligra::Sheets::Doc *doc, QGraphicsItem *parent = 0);
protected:
    void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);
};

myfile.cpp

TransparentCanvasItem::TransparentCanvasItem(Doc *doc, QGraphicsItem *parent) : CanvasItem(doc, parent)
{
}

void TransparentCanvasItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{
    Qt::BGMode origBgMode = painter->backgroundMode();
    QBrush brush, origBrush = painter->background();

    brush = origBrush;
    brush.setColor(Qt::transparent);

    painter->setBackgroundMode(Qt::TransparentMode);
    painter->setBackground(brush);

    CanvasItem::paint(painter, option, widget);

    painter->setBackground(origBrush);
    painter->setBackgroundMode(origBgMode);
}

MyGraphicsItem::~CalligraItem()
{
    if (m_part != 0)
        delete m_part;

    if (m_canvas != 0)
        delete m_canvas;

    if (m_cachedDoc != 0)
        delete m_cachedDoc;
}

void MyGraphicsItem::resize(const QSizeF& size)
{

    QRectF r = rect();
    r.setSize(size);
    setRect(r);

    if (m_canvasSet && m_canvas != 0) {
        m_canvas->resetTransform();
        switch (m_scaleMode) {
        case (MyGraphicsItem::ScaleToItem):
            m_canvas->scale(size.width() / m_canvas->boundingRect().size().width(), size.height() / m_canvas->boundingRect().size().height());
        break;
        default:
            m_canvas->setGeometry(r);
        }
    }
}

void MyGraphicsItem::updateFile(const QFileInfo& file)
{
    if (!file.isFile())
        return;

    Part *part = new Part(0);
    Doc *doc = new Doc(part);
    part->setDocument(doc);

    if (!doc->openUrl(KUrl(file.absoluteFilePath()))) {
        delete doc;
        return;
    }

    if (m_part != 0)
        delete m_part;

    if (m_canvas != 0) {
        m_canvas->setParentItem(0);
        m_canvas->scene()->removeItem(m_canvas);
        delete m_canvas;
    }

    if (m_cachedDoc != 0)
        delete m_cachedDoc;

    m_cachedDoc = doc;
    m_part = part;

    m_canvas = new TransparentCanvasItem (doc);
    //m_canvas = static_cast<CanvasItem*> (m_part->createCanvasItem());
    m_canvas->setParentItem(this);
}


Kind regards,

Philip

On Fri, 2012-11-30 at 14:39 +0100, Boudewijn Rempt wrote:

> On Fri, 30 Nov 2012, Philip Van Hoof wrote:
> 
> > Hi there,
> >
> > I'm trying to make the cells of a spreadsheet document which I have
> > loaded using sheets/part/CanvasItem.h, which is a GraphicsItem,
> > transparent.
> 
> 
> Hm... let's see. The basic painting code is in CanvasBase.cpp, where line 
> 477 says
> 
> painter->fillRect(paintRect, painter->background());
> 
> But where is the background on the QPainter object set... I think we need 
> Mek to figure that out. You could hack your version of sheets' canvasbase 
> here to something like
> 
> Qt::BGMode bgMode = painter->backgroundMode();
> painter->setBackgroundMode(Qt::TransparentMode();
> 
> ...
> 
> painter->setBackgroundMode(bgMode);
> 
> sheet->backgroundImageProperties are something different, I think -- it 
> must be meant to show an actual image as specified by the document, like a 
> watermark.
> 
> QGraphicsItem::setOpacity also isn't what you need, since that would set 
> the opacity for everything including the cell foregrounds.
> 
> >
> > I tried the following code, but although the result is that the color of
> > all cells changes, the color it uses isn't transparent but white. Or
> > perhaps it is transparent but there is something white behind the cells
> > anyway.
> >
> > QGraphicsRectItem rect;
> >
> > Part *part = new Part(0);
> > Doc *doc = new Doc(part);
> > part->setDocument(doc);
> >
> > CanvasItem *m_canvas = new CanvasItem (doc);
> > m_canvas->setParentItem(&rect);
> >
> > Sheet *sheet = m_canvas->activeSheet();
> >
> > Calligra::Sheets::Region region = Calligra::Sheets::Region(1, 1, KS_colMax, KS_rowMax);
> >
> > Style style;
> > QBrush brush;
> > brush.setColor(Qt::transparent);
> > style.setBackgroundBrush(brush);
> > style.setBackgroundColor(Qt::transparent);
> >
> > Sheet::BackgroundImageProperties props = sheet->backgroundImageProperties();
> > props.opacity = 0;
> > sheet->setBackgroundImageProperties( props );
> >
> > CellStorage *cells = sheet->cellStorage();
> > cells->setStyle(region, style);
> >
> > scene.addItem(&rect);
> >
> > Does somebody know how I can make it be truly transparent? Is there
> > something being drawn behind the CellView instances that is white? Like
> > a background maybe?
> >
> > I noticed the existence of the API sheet->setBackgroundImageProperties.
> > As you can see above I tried using it, but it didn't change much.
> >
> > If I would have to patch Calligra to make this effect possible, where
> > should I start looking?
> >
> > Kind regards,
> >
> > Philip
> >
> >
> >
> > -- 
> >
> >
> > Philip Van Hoof
> > Software developer
> > Codeminded BVBA - http://codeminded.be
> >
> > _______________________________________________
> > calligra-devel mailing list
> > calligra-devel at kde.org
> > https://mail.kde.org/mailman/listinfo/calligra-devel
> >
> _______________________________________________
> calligra-devel mailing list
> calligra-devel at kde.org
> https://mail.kde.org/mailman/listinfo/calligra-devel
> 


-- 


Philip Van Hoof
Software developer
Codeminded BVBA - http://codeminded.be
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/calligra-devel/attachments/20121203/2de7f2e6/attachment.htm>


More information about the calligra-devel mailing list