diff --git a/libs/libkis/Node.cpp b/libs/libkis/Node.cpp index b27d79d5cf..8369adf521 100644 --- a/libs/libkis/Node.cpp +++ b/libs/libkis/Node.cpp @@ -1,514 +1,473 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Krita.h" #include "Node.h" #include "Channel.h" #include "Generator.h" #include "Filter.h" #include "Transformation.h" #include "Selection.h" struct Node::Private { Private() {} KisImageSP image; KisNodeSP node; }; Node::Node(KisImageSP image, KisNodeSP node, QObject *parent) : QObject(parent) , d(new Private) { d->image = image; d->node = node; } Node::~Node() { delete d; } bool Node::alphaLocked() const { if (!d->node) return false; KisPaintLayerSP paintLayer = qobject_cast(d->node.data()); if (paintLayer) { return paintLayer->alphaLocked(); } return false; } void Node::setAlphaLocked(bool value) { if (!d->node) return; KisPaintLayerSP paintLayer = qobject_cast(d->node.data()); if (paintLayer) { paintLayer->setAlphaLocked(value); } } QString Node::blendingMode() const { if (!d->node) return QString(); return d->node->compositeOpId(); } void Node::setBlendingMode(QString value) { if (!d->node) return; d->node->setCompositeOpId(value); } QList Node::channels() const { QList channels; if (!d->node) return channels; if (!d->node->inherits("KisLayer")) return channels; Q_FOREACH(KoChannelInfo *info, d->node->colorSpace()->channels()) { Channel *channel = new Channel(d->node, info); channels << channel; } return channels; } QList Node::childNodes() const { QList nodes; if (d->node) { int childCount = d->node->childCount(); for (int i = 0; i < childCount; ++i) { nodes << new Node(d->image, d->node->at(i)); } } return nodes; } bool Node::addChildNode(Node *child, Node *above) { if (!d->node) return false; return d->image->addNode(child->node(), d->node, above->node()); } bool Node::removeChildNode(Node *child) { if (!d->node) return false; return d->image->removeNode(child->node()); } void Node::setChildNodes(QList nodes) { if (!d->node) return; KisNodeSP node = d->node->firstChild(); while (node) { d->image->removeNode(node); node = node->nextSibling(); } Q_FOREACH(Node *node, nodes) { d->image->addNode(node->node(), d->node); } } int Node::colorLabel() const { if (!d->node) return 0; return d->node->colorLabelIndex(); } void Node::setColorLabel(int index) { if (!d->node) return; d->node->setColorLabelIndex(index); } QString Node::colorDepth() const { if (!d->node) return ""; return d->node->colorSpace()->colorDepthId().id(); } QString Node::colorModel() const { if (!d->node) return ""; return d->node->colorSpace()->colorModelId().id(); } QString Node::colorProfile() const { if (!d->node) return ""; return d->node->colorSpace()->profile()->name(); } void Node::setColorProfile(const QString &colorProfile) { // UNIMPLEMENTED } void Node::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile) { // UNIMPLEMENTED } +bool Node::animated() const +{ + if (!d->node) return false; + return d->node->isAnimated(); +} + +void Node::enableAnimation() const +{ + if (!d->node) return; + d->node->enableAnimation(); +} + +bool Node::collapsed() const +{ + if (!d->node) return false; + return d->node->collapsed(); +} + +void Node::setCollapsed(bool collapsed) +{ + if (!d->node) return; + d->node->setCollapsed(collapsed); +} bool Node::inheritAlpha() const { - // UNIMPLEMENTED if (!d->node) return false; - return false; + if (!d->node->inherits("KisLayer")) return false; + return qobject_cast(d->node)->alphaChannelDisabled(); } void Node::setInheritAlpha(bool value) { - // UNIMPLEMENTED if (!d->node) return; + if (!d->node->inherits("KisLayer")) return; + const_cast(qobject_cast(d->node))->disableAlphaChannel(value); } - bool Node::locked() const { - // UNIMPLEMENTED if (!d->node) return false; - return false; + return d->node->userLocked() || d->node->systemLocked(); } void Node::setLocked(bool value) { - // UNIMPLEMENTED if (!d->node) return; + d->node->setUserLocked(value); } QString Node::name() const { if (!d->node) return QString(); return d->node->name(); } -void Node::setName(QString value) +void Node::setName(QString name) { - // UNIMPLEMENTED if (!d->node) return; + d->node->setName(name); } int Node::opacity() const { if (!d->node) return 0; return d->node->opacity(); } void Node::setOpacity(int value) { if (!d->node) return; d->node->setOpacity(value); } Node* Node::parentNode() const { - // UNIMPLEMENTED if (!d->node) return 0; - return 0; + return new Node(d->image, d->node->parent()); } QString Node::type() const { if (!d->node) return QString(); return QString(); if (qobject_cast(d->node)) { return "paintlayer"; } else if (qobject_cast(d->node)) { return "grouplayer"; } if (qobject_cast(d->node)) { return "filelayer"; } if (qobject_cast(d->node)) { return "filterlayer"; } if (qobject_cast(d->node)) { return "filllayer"; } if (qobject_cast(d->node)) { return "clonelayer"; } if (qobject_cast(d->node)) { return "shapelayer"; } if (qobject_cast(d->node)) { return "transparencymask"; } if (qobject_cast(d->node)) { return "filtermask"; } if (qobject_cast(d->node)) { return "transformmask"; } if (qobject_cast(d->node)) { return "selectionmask"; } if (qobject_cast(d->node)) { return "colorizemask"; } } bool Node::visible() const { - // UNIMPLEMENTED if (!d->node) return false; - return false; -} - -void Node::setVisible(bool value) -{ - // UNIMPLEMENTED - if (!d->node) return; -} - - -InfoObject* Node::metaDataInfo() const -{ - // UNIMPLEMENTED - if (!d->node) return 0; - return 0; + return d->node->visible();; } -void Node::setMetaDataInfo(InfoObject* value) +void Node::setVisible(bool visible) { - // UNIMPLEMENTED if (!d->node) return; + d->node->setVisible(visible); } -Generator* Node::generator() const -{ - // UNIMPLEMENTED - if (!d->node) return 0; - return 0; -} - -void Node::setGenerator(Generator* value) -{ - // UNIMPLEMENTED - if (!d->node) return; -} - - -Filter* Node::filter() const -{ - // UNIMPLEMENTED - if (!d->node) return 0; - return 0; -} - -void Node::setFilter(Filter* value) -{ - // UNIMPLEMENTED - if (!d->node) return; -} - - -Transformation* Node::transformation() const -{ - // UNIMPLEMENTED - if (!d->node) return 0; - return 0; -} - -void Node::setTransformation(Transformation* value) -{ - // UNIMPLEMENTED - if (!d->node) return; -} - -QString Node::fileName() const -{ - // UNIMPLEMENTED - if (!d->node) return QString(); - return QString(); -} - -void Node::setFileName(QString value) -{ - // UNIMPLEMENTED - if (!d->node) return; -} - QByteArray Node::pixelData(int x, int y, int w, int h) const { QByteArray ba; if (!d->node) return ba; KisPaintDeviceSP dev = d->node->paintDevice(); if (!dev) return ba; quint8 *data = new quint8[w * h * dev->pixelSize()]; dev->readBytes(data, x, y, w, h); ba = QByteArray((const char*)data, (int)(w * h * dev->pixelSize())); delete[] data; return ba; } QByteArray Node::projectionPixelData(int x, int y, int w, int h) const { QByteArray ba; if (!d->node) return ba; KisPaintDeviceSP dev = d->node->projection(); quint8 *data = new quint8[w * h * dev->pixelSize()]; dev->readBytes(data, x, y, w, h); ba = QByteArray((const char*)data, (int)(w * h * dev->pixelSize())); delete[] data; return ba; } void Node::setPixelData(QByteArray value, int x, int y, int w, int h) { if (!d->node) return; KisPaintDeviceSP dev = d->node->paintDevice(); if (!dev) return; dev->writeBytes((const quint8*)value.constData(), x, y, w, h); } QRect Node::bounds() const { if (!d->node) return QRect(); return d->node->exactBounds(); } void Node::move(int x, int y) { - // UNIMPLEMENTED if (!d->node) return; + d->node->setX(x); + d->node->setY(y); } -void Node::moveToParent(Node *parent) +QPoint Node::position() const { - // UNIMPLEMENTED - if (!d->node) return; + if (!d->node) return QPoint(); + return QPoint(d->node->x(), d->node->y()); } bool Node::remove() { if (!d->node) return false; if (!d->node->parent()) return false; return d->image->removeNode(d->node); } Node* Node::duplicate() { if (!d->node) return 0; return new Node(d->image, d->node->clone()); } bool Node::save(const QString &filename, double xRes, double yRes) { if (!d->node) return false; if (filename.isEmpty()) return false; KisPaintDeviceSP projection = d->node->projection(); QRect bounds = d->node->exactBounds(); QString mimefilter = KisMimeDatabase::mimeTypeForFile(filename);; QScopedPointer doc(KisPart::instance()->createDocument()); KisImageSP dst = new KisImage(doc->createUndoStore(), bounds.width(), bounds.height(), projection->compositionSourceColorSpace(), d->node->name()); dst->setResolution(xRes, yRes); doc->setFileBatchMode(Krita::instance()->batchmode()); doc->setCurrentImage(dst); KisPaintLayer* paintLayer = new KisPaintLayer(dst, "paint device", d->node->opacity()); paintLayer->paintDevice()->makeCloneFrom(projection, bounds); dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0)); dst->initialRefreshGraph(); doc->setOutputMimeType(mimefilter.toLatin1()); bool r = doc->exportDocument(QUrl::fromLocalFile(filename)); if (!r) { qWarning() << doc->errorMessage(); } return r; } Node *Node::mergeDown() { if (!d->node) return 0; if (!qobject_cast(d->node.data())) return 0; if (!d->node->prevSibling()) return 0; KisLayerSP layer = qobject_cast(d->node->prevSibling().data()); if (!layer) return 0; d->image->mergeDown(qobject_cast(d->node.data()), KisMetaData::MergeStrategyRegistry::instance()->get("Drop")); return new Node(d->image, layer); } +QImage Node::thumbnail(int w, int h) +{ + if (!d->node) return QImage(); + return d->node->createThumbnail(w, h); +} + KisPaintDeviceSP Node::paintDevice() const { return d->node->paintDevice(); } KisImageSP Node::image() const { return d->image; } KisNodeSP Node::node() const { return d->node; } diff --git a/libs/libkis/Node.h b/libs/libkis/Node.h index 088e55ceb2..5e00e58278 100644 --- a/libs/libkis/Node.h +++ b/libs/libkis/Node.h @@ -1,400 +1,425 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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. */ #ifndef LIBKIS_NODE_H #define LIBKIS_NODE_H #include #include #include "kritalibkis_export.h" #include "libkis.h" /** * Node */ class KRITALIBKIS_EXPORT Node : public QObject { Q_OBJECT Q_DISABLE_COPY(Node) public: explicit Node(KisImageSP image, KisNodeSP node, QObject *parent = 0); virtual ~Node(); public Q_SLOTS: /** * @brief alphaLocked checks whether the node is a paint layer and returns whether it is alpha locked * @return whether the paint layer is alpha locked, or false if the node is not a paint layer */ bool alphaLocked() const; /** * @brief setAlphaLocked set the layer to value if the the node is paint layer. */ void setAlphaLocked(bool value); /** * @return the blending mode of the layer. The values of the blending modes are defined in @see KoCompositeOpRegistry.h */ QString blendingMode() const; /** * @brief setBlendingMode set the blending mode of the node to the given value * @param value one of the string values from @see KoCompositeOpRegistry.h */ void setBlendingMode(QString value); /** * @brief channels creates a list of Channel objects that can be used individually to * show or hide certain channels, and to retrieve the contents of each channel in a * node separately. * * Only layers have channels, masks do not, and calling channels on a Node that is a mask * will return an empty list. * * @return the list of channels ordered in by position of the channels in pixel position */ QList channels() const; /** * Return a list of child nodes of the current node. The nodes are ordered from the bottommost up. * The function is not recursive. */ QList childNodes() const; /** * @brief addChildNode adds the given node in the list of children. * @param child the node to be added * @param above the node above which this node will be placed * @return false if adding the node failed */ bool addChildNode(Node *child, Node *above); /** * @brief removeChildNode removes the given node from the list of children. * @param child the node to be removed */ bool removeChildNode(Node *child); /** * @brief setChildNodes this replaces the existing set of child nodes with the new set. * @param nodes The list of nodes that will become children, bottom-up -- the first node, * is the bottom-most node in the stack. */ void setChildNodes(QList nodes); /** * colorDepth A string describing the color depth of the image: *
    *
  • U8: unsigned 8 bits integer, the most common type
  • *
  • U16: unsigned 16 bits integer
  • *
  • F16: half, 16 bits floating point. Only available if Krita was built with OpenEXR
  • *
  • F32: 32 bits floating point
  • *
* @return the color depth. */ QString colorDepth() const; /** * @brief colorModel retrieve the current color model of this document: *
    *
  • A: Alpha mask
  • *
  • RGBA: RGB with alpha channel (The actual order of channels is most often BGR!)
  • *
  • XYZA: XYZ with alpha channel
  • *
  • LABA: LAB with alpha channel
  • *
  • CMYKA: CMYK with alpha channel
  • *
  • GRAYA: Gray with alpha channel
  • *
  • YCbCrA: YCbCr with alpha channel
  • *
* @return the internal color model string. */ QString colorModel() const; /** * @return the name of the current color profile */ QString colorProfile() const; /** * @brief setColorProfile set the color profile of the image to the given profile. The profile has to * be registered with krita and be compatible with the current color model and depth; the image data * is not converted. * @param colorProfile */ void setColorProfile(const QString &colorProfile); /** * @brief setColorSpace convert the node to the given colorspace * @param colorModel A string describing the color model of the node: *
    *
  • A: Alpha mask
  • *
  • RGBA: RGB with alpha channel (The actual order of channels is most often BGR!)
  • *
  • XYZA: XYZ with alpha channel
  • *
  • LABA: LAB with alpha channel
  • *
  • CMYKA: CMYK with alpha channel
  • *
  • GRAYA: Gray with alpha channel
  • *
  • YCbCrA: YCbCr with alpha channel
  • *
* @param colorDepth A string describing the color depth of the image: *
    *
  • U8: unsigned 8 bits integer, the most common type
  • *
  • U16: unsigned 16 bits integer
  • *
  • F16: half, 16 bits floating point. Only available if Krita was built with OpenEXR
  • *
  • F32: 32 bits floating point
  • *
* @param colorProfile a valid color profile for this color model and color depth combinatiojn. */ void setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile); + /** + * @brief Krita layers can be animated, i.e., have frames. + * @return return true if the layer has frames + */ + bool animated() const; + + /** + * @brief enableAnimation make the current layer animated, so it can have frames. + */ + void enableAnimation() const; + + /** + * Sets the state of the node to the value of @param collapsed + */ + void setCollapsed(bool collapsed); + + /** + * returns the collapsed state of this node + */ + bool collapsed() const; + /** * Sets a color label index associated to the layer. The actual * color of the label and the number of available colors is * defined by Krita GUI configuration. */ int colorLabel() const; /** * @brief setColorLabel sets a color label index associated to the layer. The actual * color of the label and the number of available colors is * defined by Krita GUI configuration. * @param index an integer corresponding to the set of available color labels. */ void setColorLabel(int index); bool inheritAlpha() const; void setInheritAlpha(bool value); bool locked() const; void setLocked(bool value); QString name() const; - void setName(QString value); + void setName(QString name); int opacity() const; void setOpacity(int value); Node* parentNode() const; /** * @brief type Krita has several types of nodes, split in layers and masks. Group * layers can contain other layers, any layer can contain masks. * * @return The type of the node. Valid types are: *
    *
  • paintlayer *
  • grouplayer *
  • filelayer *
  • filterlayer *
  • filllayer *
  • clonelayer *
  • vectorlayer *
  • transparencymask *
  • filtermask *
  • transformmask *
  • selectionmask *
  • colorizemask *
* * If the Node object isn't wrapping a valid Krita layer or mask object, and * empty string is returned. */ QString type() const; bool visible() const; - void setVisible(bool value); - - InfoObject* metaDataInfo() const; - void setMetaDataInfo(InfoObject* value); - - Generator* generator() const; - void setGenerator(Generator* value); - - Filter* filter() const; - void setFilter(Filter* value); - - Transformation* transformation() const; - void setTransformation(Transformation* value); - - QString fileName() const; - void setFileName(QString value); + void setVisible(bool visible); /** * @brief pixelData reads the given rectangle from the Node's paintable pixels, if those * exist, and returns it as a byte array. The pixel data starts top-left, and is ordered row-first. * * The byte array can be interpreted as follows: 8 bits images have one byte per channel, * and as many bytes as there are channels. 16 bits integer images have two bytes per channel, * representing an unsigned short. 16 bits float images have two bytes per channel, representing * a half, or 16 bits float. 32 bits float images have four bytes per channel, representing a * float. * * You can read outside the node boundaries; those pixels will be transparent black. * * The order of channels is: * *
    *
  • Integer RGBA: Blue, Green, Red, Alpha *
  • Float RGBA: Red, Green, Blue, Alpha *
  • GrayA: Gray, Alpha *
  • Selection: selectedness *
  • LabA: L, a, b, Alpha *
  • CMYKA: Cyan, Magenta, Yellow, Key, Alpha *
  • XYZA: X, Y, Z, A *
  • YCbCrA: Y, Cb, Cr, Alpha *
* * The byte array is a copy of the original node data. In Python, you can use bytes, bytearray * and the struct module to interpret the data and construct, for instance, a Pillow Image object. * * If you read the pixeldata of a mask, a filter or generator layer, you get the selection bytes, * which is one channel with values in the range from 0..255. * * If you want to change the pixels of a node you can write the pixels back after manipulation * with setPixelData(). This will only succeed on nodes with writable pixel data, e.g not on groups * or file layers. * * @param x x position from where to start reading * @param y y position from where to start reading * @param w row length to read * @param h number of rows to read * @return a QByteArray with the pixel data. The byte array may be empty. */ QByteArray pixelData(int x, int y, int w, int h) const; /** * @brief projectionPixelData reads the given rectangle from the Node's projection (that is, what the node * looks like after all sub-Nodes (like layers in a group or masks on a layer) have been applied, * and returns it as a byte array. The pixel data starts top-left, and is ordered row-first. * * The byte array can be interpreted as follows: 8 bits images have one byte per channel, * and as many bytes as there are channels. 16 bits integer images have two bytes per channel, * representing an unsigned short. 16 bits float images have two bytes per channel, representing * a half, or 16 bits float. 32 bits float images have four bytes per channel, representing a * float. * * You can read outside the node boundaries; those pixels will be transparent black. * * The order of channels is: * *
    *
  • Integer RGBA: Blue, Green, Red, Alpha *
  • Float RGBA: Red, Green, Blue, Alpha *
  • GrayA: Gray, Alpha *
  • Selection: selectedness *
  • LabA: L, a, b, Alpha *
  • CMYKA: Cyan, Magenta, Yellow, Key, Alpha *
  • XYZA: X, Y, Z, A *
  • YCbCrA: Y, Cb, Cr, Alpha *
* * The byte array is a copy of the original node data. In Python, you can use bytes, bytearray * and the struct module to interpret the data and construct, for instance, a Pillow Image object. * * If you read the projection of a mask, you get the selection bytes, which is one channel with * values in the range from 0..255. * * If you want to change the pixels of a node you can write the pixels back after manipulation * with setPixelData(). This will only succeed on nodes with writable pixel data, e.g not on groups * or file layers. * * @param x x position from where to start reading * @param y y position from where to start reading * @param w row length to read * @param h number of rows to read * @return a QByteArray with the pixel data. The byte array may be empty. */ QByteArray projectionPixelData(int x, int y, int w, int h) const; /** * @brief setPixelData writes the given bytes, of which there must be enough, into the * Node, if the Node has writable pixel data: * *
    *
  • paint layer: the layer's original pixels are overwritten *
  • filter layer, generator layer, any mask: the embedded selection's pixels are overwritten. * Note: for these *
* * File layers, Group layers, Clone layers cannot be written to. Calling setPixelData on * those layer types will silently do nothing. * * @param value the byte array representing the pixels. There must be enough bytes available. * Krita will take the raw pointer from the QByteArray and start reading, not stopping before * (number of channels * size of channel * w * h) bytes are read. * * @param x the x position to start writing from * @param y the y position to start writing from * @param w the width of each row * @param h the number of rows to write */ void setPixelData(QByteArray value, int x, int y, int w, int h); + /** + * @brief bounds return the exact bounds of the node's paint device + * @return the bounds, or an empty QRect if the node has no paint device or is empty. + */ QRect bounds() const; + /** + * move the pixels to the given x, y location in the image coordinate space. + */ void move(int x, int y); - void moveToParent(Node *parent); + /** + * @brief position returns the position of the paint device of this node + * @return the top-left position of the node + */ + QPoint position() const; /** * @brief remove removes this node from its parent image. */ bool remove(); /** * @brief duplicate returns a full copy of the current node. The node is not inserted in the graphc * @return a valid Node object or 0 if the node couldn't be duplicated. */ Node* duplicate(); /** * @brief save exports the given node with this filename. The extension of the filename determins the filetype. * @param filename the filename including extension * @param xRes the horizontal resolution in pixels per pt (there are 72 pts in an inch) * @param yRes the horizontal resolution in pixels per pt (there are 72 pts in an inch) * @return true if saving succeeded, false if it failed. */ bool save(const QString &filename, double xRes, double yRes); /** * @brief mergeDown merges the given node with the first visible node underneath this node in the layerstack. * This will drop all per-layer metadata. * @param node the node to merge down; this node will be removed from the layer stack */ Node *mergeDown(); + /** + * @brief thumbnail create a thumbnail of the given dimensions. The thumbnail is sized according + * to the layer dimensions, not the image dimensions. If the requested size is too big a null + * QImage is created. If the current node cannot generate a thumbnail, a transparent QImage of the + * requested size is generated. + * @return a QImage representing the layer contents. + */ + QImage thumbnail(int w, int h); private: friend class Filter; friend class Document; friend class Selection; /** * @brief paintDevice gives access to the internal paint device of this Node * @return the paintdevice or 0 if the node does not have an editable paint device. */ KisPaintDeviceSP paintDevice() const; KisImageSP image() const; KisNodeSP node() const; struct Private; Private *const d; }; #endif // LIBKIS_NODE_H diff --git a/plugins/extensions/pykrita/sip/krita/Node.sip b/plugins/extensions/pykrita/sip/krita/Node.sip index 60651a88b3..445f34915b 100644 --- a/plugins/extensions/pykrita/sip/krita/Node.sip +++ b/plugins/extensions/pykrita/sip/krita/Node.sip @@ -1,59 +1,54 @@ class Node : QObject { %TypeHeaderCode #include "Node.h" %End Node(const Node & __0); public: virtual ~Node(); public Q_SLOTS: bool alphaLocked() const; void setAlphaLocked(bool value); QString blendingMode() const; void setBlendingMode(QString value); QList channels() const; QList childNodes() const; bool addChildNode(Node *child, Node *above); bool removeChildNode(Node *child); void setChildNodes(QList nodes); QString colorDepth() const; + bool animated() const; + void enableAnimation() const; + void setCollapsed(bool collapsed); + bool collapsed() const; int colorLabel() const; void setColorLabel(int value); QString colorModel() const; QString colorProfile() const; void setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile); bool inheritAlpha() const; void setInheritAlpha(bool value); bool locked() const; void setLocked(bool value); QString name() const; void setName(QString value); int opacity() const; void setOpacity(int value); Node * parentNode() const /Factory/; QString type() const; bool visible() const; void setVisible(bool value); - InfoObject * metaDataInfo() const /Factory/; - void setMetaDataInfo(InfoObject* value); - Generator * generator() const /Factory/; - void setGenerator(Generator* value); - Filter * filter() const /Factory/; - void setFilter(Filter* value); - Transformation * transformation() const; - void setTransformation(Transformation* value); - QString fileName() const; - void setFileName(QString value); QByteArray pixelData(int x, int y, int w, int h) const; QByteArray projectionPixelData(int x, int y, int w, int h) const; void setPixelData(QByteArray value, int x, int y, int w, int h); QRect bounds() const; void move(int x, int y); - void moveToParent(Node* parent); + QPoint position() const; bool remove(); Node *duplicate() /Factory/; void save(const QString &filename, double xRes, double yRes); Node *mergeDown() /Factory/; + QImage thumbnail(int w, int h); Q_SIGNALS: private: };