summaryrefslogtreecommitdiffstats
path: root/chalk/ui/kis_part_layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chalk/ui/kis_part_layer.cpp')
-rw-r--r--chalk/ui/kis_part_layer.cpp260
1 files changed, 260 insertions, 0 deletions
diff --git a/chalk/ui/kis_part_layer.cpp b/chalk/ui/kis_part_layer.cpp
new file mode 100644
index 000000000..4c05360eb
--- /dev/null
+++ b/chalk/ui/kis_part_layer.cpp
@@ -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 <tdelocale.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->parentDocument()->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 repaint where we currently updated
+ // We use the original geometry
+ if (m_activated && !activated /* no clue, but debugging suggests it is false here */) {
+ TQPtrList<KoView> views = m_doc->parentDocument()->views();
+ Q_ASSERT(views.count());
+ views.at(0)->disconnect(TQT_SIGNAL(activated(bool)));
+ m_activated = false;
+ setDirty(m_doc->geometry());
+ }
+}
+
+void KisPartLayerImpl::setX(TQ_INT32 x) {
+ TQRect rect = m_doc->geometry();
+
+ // 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->geometry();
+
+ // 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->geometry();
+
+ for (int y2 = y; y2 < h + y; ++y2) {
+ for (int x2 = x; x2 < w + x; ++x2) {
+ if (!rect.contains(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"