diff options
Diffstat (limited to 'chalk/ui/kis_part_layer.cc')
-rw-r--r-- | chalk/ui/kis_part_layer.cc | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/chalk/ui/kis_part_layer.cc b/chalk/ui/kis_part_layer.cc new file mode 100644 index 00000000..401721b5 --- /dev/null +++ b/chalk/ui/kis_part_layer.cc @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "tqpaintdevice.h" +#include "tqpixmap.h" +#include "tqimage.h" +#include "tqpainter.h" + +#include <klocale.h> + +#include "KoDocument.h" +#include "KoDocumentChild.h" +#include "KoFrame.h" +#include "KoView.h" + +#include "kis_layer.h" +#include "kis_types.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_part_layer.h" +#include "kis_group_layer.h" +#include "kis_factory.h" +#include "kis_paint_device.h" +#include <kis_meta_registry.h> + +KisChildDoc::KisChildDoc ( KisDoc * kisDoc, const TQRect & rect, KoDocument * childDoc ) + : KoDocumentChild( kisDoc, childDoc, rect ) + , m_doc(kisDoc) + , m_partLayer(0) +{ +} + + +KisChildDoc::KisChildDoc ( KisDoc * kisDoc ) + : KoDocumentChild( kisDoc) + , m_partLayer(0) +{ +} + +KisChildDoc::~KisChildDoc () +{ + // XXX doesn't this get deleted by itself or by anything else? Certainly looks so + // (otherwise I get a double deletion of a TQObject, and chalk crashes) + //delete m_doc; +} + + +KisPartLayerImpl::KisPartLayerImpl(KisImageSP img, KisChildDoc * doc) + : super(img, i18n("Embedded Document"), OPACITY_OPAQUE), m_doc(doc) +{ + m_cache = new KisPaintDevice( + KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),""), name().latin1() ); + m_activated = false; +} + +KisPartLayerImpl::~KisPartLayerImpl() +{ +} + +KisLayerSP KisPartLayerImpl::clone() const { + return new KisPartLayerImpl(image(), childDoc()); +} + +// Called when the layer is made active +void KisPartLayerImpl::childActivated(KoDocumentChild* child) +{ + // Clear the image, so that if we move the part while activated, no ghosts show up + if (!m_activated && child == m_doc) { + TQRect rect = extent(); + m_activated = true; + setDirty(rect); + TQPtrList<KoView> views = child->tqparentDocument()->views(); + Q_ASSERT(views.count()); + // XXX iterate over views + connect(views.at(0), TQT_SIGNAL(activated(bool)), + this, TQT_SLOT(childDeactivated(bool))); + } +} + +// Called when another layer is made inactive +void KisPartLayerImpl::childDeactivated(bool activated) +{ + // We probably changed, notify the image that it needs to tqrepaint where we currently updated + // We use the original tqgeometry + if (m_activated && !activated /* no clue, but debugging suggests it is false here */) { + TQPtrList<KoView> views = m_doc->tqparentDocument()->views(); + Q_ASSERT(views.count()); + views.at(0)->disconnect(TQT_SIGNAL(activated(bool))); + m_activated = false; + setDirty(m_doc->tqgeometry()); + } +} + +void KisPartLayerImpl::setX(TQ_INT32 x) { + TQRect rect = m_doc->tqgeometry(); + + // KisPaintDevice::move moves to absolute coordinates, not relative. Work around that here, + // since the part is not necesarily started at (0,0) + rect.moveBy(x - this->x(), 0); + m_doc->setGeometry(rect); +} + +void KisPartLayerImpl::setY(TQ_INT32 y) { + TQRect rect = m_doc->tqgeometry(); + + // KisPaintDevice::move moves to absolute coordinates, not relative. Work around that here, + // since the part is not necesarily started at (0,0) + rect.moveBy(0, y - this->y()); + m_doc->setGeometry(rect); +} + +void KisPartLayerImpl::paintSelection(TQImage &img, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) { + uchar *j = img.bits(); + TQRect rect = m_doc->tqgeometry(); + + for (int y2 = y; y2 < h + y; ++y2) { + for (int x2 = x; x2 < w + x; ++x2) { + if (!rect.tqcontains(x2, y2)) { + TQ_UINT8 g = (*(j + 0) + *(j + 1 ) + *(j + 2 )) / 9; + *(j+0) = 165+g; + *(j+1) = 128+g; + *(j+2) = 128+g; + } + j+=4; + } + } + +} + +KisPaintDeviceSP KisPartLayerImpl::prepareProjection(KisPaintDeviceSP projection, const TQRect& r) +{ + if (!m_doc || !m_doc->document() || m_activated) return 0; + + m_cache->clear(); + + TQRect intersection(r.intersect(exactBounds())); + if (intersection.isEmpty()) + return m_cache; + // XXX: have a look at the comments and see if they still truthfully represent the code :/ + + // We know the embedded part's size through the ChildDoc + // We move it to (0,0), since that is what we will start painting from in paintEverything. + TQRect embedRect(intersection); + embedRect.moveBy(- exactBounds().x(), - exactBounds().y()); + TQRect paintRect(exactBounds()); + paintRect.moveBy(- exactBounds().x(), - exactBounds().y()); + + TQPixmap pm1(projection->convertToTQImage(0 /*srgb XXX*/, + intersection.x(), intersection.y(), + intersection.width(), intersection.height())); + TQPixmap pm2(extent().width(), extent().height()); + copyBlt(&pm2, embedRect.x(), embedRect.y(), &pm1, + 0, 0, embedRect.width(), embedRect.height()); + TQPainter painter(&pm2); + painter.setClipRect(embedRect); + + // KWord's KWPartFrameSet::drawFrameContents has some interesting remarks concerning + // the semantics of the paintEverything call. + // Since a Chalk Device really is displaysize/zoom agnostic, caring about zoom is not + // really as important here. What we paint at the moment, is just (0,0)x(w,h) + // Paint transparent, no zoom: + m_doc->document()->paintEverything(painter, paintRect, true); + + copyBlt(&pm1, 0, 0, &pm2, + embedRect.x(), embedRect.y(), embedRect.width(), embedRect.height()); + TQImage qimg = pm1.convertToImage(); + + //assume the part is sRGB for now, and that "" is sRGB + // And we need to paint offsetted + m_cache->convertFromTQImage(qimg, "", intersection.left(), intersection.top()); + + return m_cache; +} + +TQImage KisPartLayerImpl::createThumbnail(TQ_INT32 w, TQ_INT32 h) { + TQRect bounds(exactBounds()); + TQPixmap pm(w, h); + TQPainter painter(&pm); + + painter.fillRect(0, 0, w, h, TQt::white); + + painter.scale(w / bounds.width(), h / bounds.height()); + m_doc->document()->paintEverything(painter, bounds); + TQImage qimg = pm.convertToImage(); + + return qimg; +} + +bool KisPartLayerImpl::saveToXML(TQDomDocument doc, TQDomElement elem) +{ + TQDomElement embeddedElement = doc.createElement("layer"); + embeddedElement.setAttribute("name", name()); + + // x and y are loaded from the rect element in the embedded object tag + embeddedElement.setAttribute("x", 0); + embeddedElement.setAttribute("y", 0); + + embeddedElement.setAttribute("opacity", opacity()); + embeddedElement.setAttribute("compositeop", compositeOp().id().id()); + embeddedElement.setAttribute("visible", visible()); + embeddedElement.setAttribute("locked", locked()); + embeddedElement.setAttribute("layertype", "partlayer"); + elem.appendChild(embeddedElement); + + TQDomElement objectElem = childDoc()->save(doc); + embeddedElement.appendChild(objectElem); + + return true; +} + +KisConnectPartLayerVisitor::KisConnectPartLayerVisitor(KisImageSP img, KisView* view, bool mode) + : m_img(img), m_view(view), m_connect(mode) +{ +} + +bool KisConnectPartLayerVisitor::visit(KisGroupLayer *layer) { + KisLayerSP child = layer->lastChild(); + + while (child) { + child->accept(*this); + child = child->prevSibling(); + } + + return true; +} + +bool KisConnectPartLayerVisitor::visit(KisPartLayer *layer) { + if (m_connect) { + TQObject::connect(m_view, TQT_SIGNAL(childActivated(KoDocumentChild*)), + layer, TQT_SLOT(childActivated(KoDocumentChild*))); + } else { + TQObject::disconnect(m_view, TQT_SIGNAL(childActivated(KoDocumentChild*)), layer, 0 ); + } + + return true; +} + +bool KisConnectPartLayerVisitor::visit(KisPaintLayer*) { + return true; +} + +bool KisConnectPartLayerVisitor::visit(KisAdjustmentLayer*) { + return true; +} + +#include "kis_part_layer.moc" |