bool KisNodeManager::Private::activateNodeImpl(KisNodeSP node) { Q_ASSERT(view); Q_ASSERT(view->canvasBase()); Q_ASSERT(view->canvasBase()->globalShapeManager()); Q_ASSERT(imageView); if (node && node == q->activeNode()) { return false; } // Set the selection on the shape manager to the active layer // and set call KoSelection::setActiveLayer( KoShapeLayer* layer ) // with the parent of the active layer. KoSelection *selection = view->canvasBase()->globalShapeManager()->selection(); Q_ASSERT(selection); selection->deselectAll(); if (!node) { selection->setActiveLayer(0); imageView->setCurrentNode(0); maskManager.activateMask(0); layerManager.activateLayer(0); } else { KoShape * shape = view->document()->shapeForNode(node); Q_ASSERT(shape); selection->select(shape); KoShapeLayer * shapeLayer = dynamic_cast<KoShapeLayer*>(shape); Q_ASSERT(shapeLayer); // shapeLayer->setGeometryProtected(node->userLocked()); // shapeLayer->setVisible(node->visible()); selection->setActiveLayer(shapeLayer); imageView->setCurrentNode(node); if (KisLayerSP layer = dynamic_cast<KisLayer*>(node.data())) { maskManager.activateMask(0); layerManager.activateLayer(layer); } else if (KisMaskSP mask = dynamic_cast<KisMask*>(node.data())) { maskManager.activateMask(mask); // XXX_NODE: for now, masks cannot be nested. layerManager.activateLayer(static_cast<KisLayer*>(node->parent().data())); } } return true; }
KisNodeSP findNode(KisNodeSP node, const QPoint &point, bool wholeGroup, bool editableOnly) { KisNodeSP foundNode = 0; while (node) { KisLayerSP layer = dynamic_cast<KisLayer*>(node.data()); if (!layer || !layer->isEditable()) { node = node->prevSibling(); continue; } KoColor color(layer->projection()->colorSpace()); layer->projection()->pixel(point.x(), point.y(), &color); KisGroupLayerSP group = dynamic_cast<KisGroupLayer*>(layer.data()); if ((group && group->passThroughMode()) || color.opacityU8() != OPACITY_TRANSPARENT_U8) { if (layer->inherits("KisGroupLayer") && (!editableOnly || layer->isEditable())) { // if this is a group and the pixel is transparent, don't even enter it foundNode = findNode(node->lastChild(), point, wholeGroup, editableOnly); } else { foundNode = !wholeGroup ? node : node->parent(); } } if (foundNode) break; node = node->prevSibling(); } return foundNode; }
TransformStrokeStrategy::TransformStrokeStrategy(KisNodeSP rootNode, KisSelectionSP selection, KisPostExecutionUndoAdapter *undoAdapter) : KisStrokeStrategyUndoCommandBased(kundo2_i18n("Transform"), false, undoAdapter), m_selection(selection) { if (rootNode->childCount() || !rootNode->paintDevice()) { KisPaintDeviceSP device; if (KisTransformMask* tmask = dynamic_cast<KisTransformMask*>(rootNode.data())) { device = tmask->buildPreviewDevice(); /** * When working with transform mask, selections are not * taken into account. */ m_selection = 0; } else { rootNode->projectionLeaf()->explicitlyRegeneratePassThroughProjection(); device = rootNode->projection(); } m_previewDevice = createDeviceCache(device); } else { m_previewDevice = createDeviceCache(rootNode->paintDevice()); putDeviceCache(rootNode->paintDevice(), m_previewDevice); } Q_ASSERT(m_previewDevice); m_savedRootNode = rootNode; }
bool KisNodeFacade::moveNode(KisNodeSP node, KisNodeSP parent, quint32 newIndex) { dbgImage << "moveNode " << node << " " << parent << " " << newIndex; int oldIndex = node->parent()->index(node); if (node->graphListener()) node->graphListener()->aboutToMoveNode(node.data(), oldIndex, newIndex); KisNodeSP aboveThis = parent->at(newIndex - 1); if (aboveThis == node) return false; if (node->parent()) { if (!node->parent()->remove(node)) return false; } dbgImage << "moving node to " << newIndex; bool success = addNode(node, parent, aboveThis); if (node->graphListener()) node->graphListener()->nodeHasBeenMoved(node.data(), oldIndex, newIndex); return success; }
KisSelectionToolHelper::KisSelectionToolHelper(KisCanvas2* canvas, KisNodeSP node, const QString& name) : m_canvas(canvas) , m_layer(0) , m_name(name) { m_layer = dynamic_cast<KisLayer*>(node.data()); while (!m_layer && node->parent()) { m_layer = dynamic_cast<KisLayer*>(node->parent().data()); node = node->parent(); } m_image = m_layer->image(); }
KisFlowOpacityOption::KisFlowOpacityOption(KisNodeSP currentNode) : KisCurveOption("Opacity", KisPaintOpOption::GENERAL, true, 1.0, 0.0, 1.0) , m_flow(1.0) { setCurveUsed(true); setSeparateCurveValue(true); m_checkable = false; m_nodeHasIndirectPaintingSupport = currentNode && dynamic_cast<KisIndirectPaintingSupport*>(currentNode.data()); }
void KisInputOutputMapper::allLayers(KisNodeListSP result) { //TODO: hack ignores hierarchy introduced by group layers KisNodeSP root = m_image->rootLayer(); KisNodeSP item = root->lastChild(); while (item) { KisPaintLayer * paintLayer = dynamic_cast<KisPaintLayer*>(item.data()); if (paintLayer) { result->append(item); } item = item->prevSibling(); } }
KisSelectedTransactionData::KisSelectedTransactionData(const QString& name, KisNodeSP node, QUndoCommand* parent) : KisTransactionData(name, node->paintDevice(), parent) , m_selTransaction(0) , m_hadSelection(false /*device->hasSelection()*/) { m_layer = dynamic_cast<KisLayer*>(node.data()); while (!m_layer && node->parent()) { m_layer = dynamic_cast<KisLayer*>(node->parent().data()); node = node->parent(); } if (m_layer->selection()) m_selTransaction = new KisTransactionData(name, KisPaintDeviceSP(m_layer->selection()->getOrCreatePixelSelection().data())); // if(! m_hadSelection) { // m_device->deselect(); // let us not be the cause of select // } }
void KisRecordedFilterAction::play(KisNodeSP node, const KisPlayInfo& _info, KoUpdater* _updater) const { KisFilterConfiguration * kfc = d->configuration(); KisPaintDeviceSP dev = node->paintDevice(); KisLayerSP layer = dynamic_cast<KisLayer*>(node.data()); QRect r1 = dev->extent(); KisTransaction transaction(kundo2_i18n("Filter: \"%1\"", d->filter->name()), dev); KisImageWSP image = _info.image(); r1 = r1.intersected(image->bounds()); if (layer && layer->selection()) { r1 = r1.intersected(layer->selection()->selectedExactRect()); } d->filter->process(dev, dev, layer->selection(), r1, kfc, _updater); node->setDirty(r1); transaction.commit(_info.undoAdapter()); }
bool KisKraLoadVisitor::visit(KisCloneLayer *layer) { if (!loadMetaData(layer)) { return false; } // the layer might have already been lazily initialized // from the mask loading code if (layer->copyFrom()) { return true; } KisNodeSP srcNode = layer->copyFromInfo().findNode(m_image->rootLayer()); KisLayerSP srcLayer = qobject_cast<KisLayer*>(srcNode.data()); Q_ASSERT(srcLayer); layer->setCopyFrom(srcLayer); // Clone layers have no data except for their masks bool result = visitAll(layer); return result; }
KisFilterDialog::KisFilterDialog(KisView2 *view, KisNodeSP node, KisImageWSP image, KisSelectionSP selection) : QDialog(view), d(new Private) { setModal(false); d->uiFilterDialog.setupUi(this); d->node = node; d->image = image; d->view = view; d->mask = new KisFilterMask(); d->mask->initSelection(selection, dynamic_cast<KisLayer*>(node.data())); d->uiFilterDialog.filterSelection->setView(view); d->uiFilterDialog.filterSelection->showFilterGallery(KisConfig().showFilterGallery()); if (d->node->inherits("KisLayer")) { qobject_cast<KisLayer*>(d->node.data())->setPreviewMask(d->mask); d->uiFilterDialog.pushButtonCreateMaskEffect->show(); d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(true); connect(d->uiFilterDialog.pushButtonCreateMaskEffect, SIGNAL(pressed()), SLOT(createMask())); } else { d->uiFilterDialog.pushButtonCreateMaskEffect->hide(); } d->uiFilterDialog.pushButtonCreateMaskEffect->hide(); // TODO fixme, understand why the mask isn't created, and then remove that line d->uiFilterDialog.filterSelection->setPaintDevice(d->node->original()); d->uiFilterDialog.pushButtonOk->setGuiItem(KStandardGuiItem::ok()); d->uiFilterDialog.pushButtonCancel->setGuiItem(KStandardGuiItem::cancel()); connect(d->uiFilterDialog.pushButtonOk, SIGNAL(pressed()), SLOT(apply())); connect(d->uiFilterDialog.pushButtonOk, SIGNAL(pressed()), SLOT(accept())); connect(d->uiFilterDialog.pushButtonCancel, SIGNAL(pressed()), SLOT(reject())); connect(d->uiFilterDialog.checkBoxPreview, SIGNAL(stateChanged(int)), SLOT(previewCheckBoxChange(int))); connect(d->uiFilterDialog.filterSelection, SIGNAL(configurationChanged()), SLOT(updatePreview())); connect(this, SIGNAL(finished(int)), SLOT(close())); KConfigGroup group(KGlobal::config(), "filterdialog"); d->uiFilterDialog.checkBoxPreview->setChecked(group.readEntry("showPreview", true)); }
KisNodeSP KisKraLoader::loadNode(const KoXmlElement& element, KisImageWSP image, KisNodeSP parent) { // Nota bene: If you add new properties to layers, you should // ALWAYS define a default value in case the property is not // present in the layer definition: this helps a LOT with backward // compatibility. QString name = element.attribute(NAME, "No Name"); QUuid id = QUuid(element.attribute(UUID, QUuid().toString())); qint32 x = element.attribute(X, "0").toInt(); qint32 y = element.attribute(Y, "0").toInt(); qint32 opacity = element.attribute(OPACITY, QString::number(OPACITY_OPAQUE_U8)).toInt(); if (opacity < OPACITY_TRANSPARENT_U8) opacity = OPACITY_TRANSPARENT_U8; if (opacity > OPACITY_OPAQUE_U8) opacity = OPACITY_OPAQUE_U8; const KoColorSpace* colorSpace = 0; if ((element.attribute(COLORSPACE_NAME)).isNull()) { dbgFile << "No attribute color space for layer: " << name; colorSpace = image->colorSpace(); } else { QString colorspacename = element.attribute(COLORSPACE_NAME); QString profileProductName; convertColorSpaceNames(colorspacename, profileProductName); QString colorspaceModel = KoColorSpaceRegistry::instance()->colorSpaceColorModelId(colorspacename).id(); QString colorspaceDepth = KoColorSpaceRegistry::instance()->colorSpaceColorDepthId(colorspacename).id(); dbgFile << "Searching color space: " << colorspacename << colorspaceModel << colorspaceDepth << " for layer: " << name; // use default profile - it will be replaced later in completeLoading colorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, ""); dbgFile << "found colorspace" << colorSpace; if (!colorSpace) { m_d->errorMessages << i18n("Layer %1 specifies an unsupported color model: %2.", name, colorspacename); return 0; } } bool visible = element.attribute(VISIBLE, "1") == "0" ? false : true; bool locked = element.attribute(LOCKED, "0") == "0" ? false : true; bool collapsed = element.attribute(COLLAPSED, "0") == "0" ? false : true; // Now find out the layer type and do specific handling QString nodeType; if (m_d->syntaxVersion == 1) { nodeType = element.attribute("layertype"); if (nodeType.isEmpty()) { nodeType = PAINT_LAYER; } } else { nodeType = element.attribute(NODE_TYPE); } if (nodeType.isEmpty()) { m_d->errorMessages << i18n("Layer %1 has an unsupported type.", name); return 0; } KisNodeSP node = 0; if (nodeType == PAINT_LAYER) node = loadPaintLayer(element, image, name, colorSpace, opacity); else if (nodeType == GROUP_LAYER) node = loadGroupLayer(element, image, name, colorSpace, opacity); else if (nodeType == ADJUSTMENT_LAYER) node = loadAdjustmentLayer(element, image, name, colorSpace, opacity); else if (nodeType == SHAPE_LAYER) node = loadShapeLayer(element, image, name, colorSpace, opacity); else if (nodeType == GENERATOR_LAYER) node = loadGeneratorLayer(element, image, name, colorSpace, opacity); else if (nodeType == CLONE_LAYER) node = loadCloneLayer(element, image, name, colorSpace, opacity); else if (nodeType == FILTER_MASK) node = loadFilterMask(element, parent); else if (nodeType == TRANSFORM_MASK) node = loadTransformMask(element, parent); else if (nodeType == TRANSPARENCY_MASK) node = loadTransparencyMask(element, parent); else if (nodeType == SELECTION_MASK) node = loadSelectionMask(image, element, parent); else if (nodeType == FILE_LAYER) { node = loadFileLayer(element, image, name, opacity); } else { m_d->errorMessages << i18n("Layer %1 has an unsupported type: %2.", name, nodeType); return 0; } // Loading the node went wrong. Return empty node and leave to // upstream to complain to the user if (!node) { m_d->errorMessages << i18n("Failure loading layer %1 of type: %2.", name, nodeType); return 0; } node->setVisible(visible, true); node->setUserLocked(locked); node->setCollapsed(collapsed); node->setX(x); node->setY(y); node->setName(name); if (! id.isNull()) // if no uuid in file, new one has been generated already node->setUuid(id); if (node->inherits("KisLayer")) { KisLayer* layer = qobject_cast<KisLayer*>(node.data()); QBitArray channelFlags = stringToFlags(element.attribute(CHANNEL_FLAGS, ""), colorSpace->channelCount()); QString compositeOpName = element.attribute(COMPOSITE_OP, "normal"); layer->setChannelFlags(channelFlags); layer->setCompositeOpId(compositeOpName); if (element.hasAttribute(LAYER_STYLE_UUID)) { QString uuidString = element.attribute(LAYER_STYLE_UUID); QUuid uuid(uuidString); if (!uuid.isNull()) { KisPSDLayerStyleSP dumbLayerStyle(new KisPSDLayerStyle()); dumbLayerStyle->setUuid(uuid); layer->setLayerStyle(dumbLayerStyle); } else { warnKrita << "WARNING: Layer style for layer" << layer->name() << "contains invalid UUID" << uuidString; } } } if (node->inherits("KisGroupLayer")) { if (element.hasAttribute(PASS_THROUGH_MODE)) { bool value = element.attribute(PASS_THROUGH_MODE, "0") != "0"; KisGroupLayer *group = qobject_cast<KisGroupLayer*>(node.data()); group->setPassThroughMode(value); } } if (node->inherits("KisPaintLayer")) { KisPaintLayer* layer = qobject_cast<KisPaintLayer*>(node.data()); QBitArray channelLockFlags = stringToFlags(element.attribute(CHANNEL_LOCK_FLAGS, ""), colorSpace->channelCount()); layer->setChannelLockFlags(channelLockFlags); bool onionEnabled = element.attribute(ONION_SKIN_ENABLED, "0") == "0" ? false : true; layer->setOnionSkinEnabled(onionEnabled); bool timelineEnabled = element.attribute(VISIBLE_IN_TIMELINE, "0") == "0" ? false : true; layer->setUseInTimeline(timelineEnabled); } if (element.attribute(FILE_NAME).isNull()) { m_d->layerFilenames[node.data()] = name; } else { m_d->layerFilenames[node.data()] = element.attribute(FILE_NAME); } if (element.hasAttribute("selected") && element.attribute("selected") == "true") { m_d->selectedNodes.append(node); } if (element.hasAttribute(KEYFRAME_FILE)) { node->enableAnimation(); m_d->keyframeFilenames.insert(node.data(), element.attribute(KEYFRAME_FILE)); } return node; }
void KisRecordedPaintAction::play(KisNodeSP node, const KisPlayInfo& info) const { dbgUI << "Play recorded paint action on node : " << node->name() ; KisTransaction * cmd = 0; if (info.undoAdapter()) cmd = new KisTransaction("", node->paintDevice()); KisPaintDeviceSP target = 0; if (d->paintIncremental) { target = node->paintDevice(); } else { target = new KisPaintDevice(node->paintDevice()->colorSpace()); } KisPainter painter(target); KisImageSP image; KisNodeSP parent = node; while (image == 0 && parent->parent()) { // XXX: ugly! KisLayerSP layer = dynamic_cast<KisLayer*>(parent.data()); if (layer) { image = layer->image(); } parent = parent->parent(); } painter.setPaintOpPreset(d->paintOpPreset, image); if (d->paintIncremental) { painter.setCompositeOp(d->compositeOp); painter.setOpacity(d->opacity); } else { painter.setCompositeOp(node->paintDevice()->colorSpace()->compositeOp(COMPOSITE_ALPHA_DARKEN)); painter.setOpacity(OPACITY_OPAQUE); } painter.setPaintColor(d->foregroundColor); painter.setFillColor(d->backgroundColor); playPaint(info, &painter); if (!d->paintIncremental) { KisPainter painter2(node->paintDevice()); painter2.setCompositeOp(d->compositeOp); painter2.setOpacity(d->opacity); QRegion r = painter.dirtyRegion(); QVector<QRect> dirtyRects = r.rects(); QVector<QRect>::iterator it = dirtyRects.begin(); QVector<QRect>::iterator end = dirtyRects.end(); while (it != end) { painter2.bitBlt(it->topLeft(), target, *it); ++it; } node->setDirty(painter2.dirtyRegion()); } else { node->setDirty(painter.dirtyRegion()); } if (info.undoAdapter()) info.undoAdapter()->addCommand(cmd); }
static inline bool isLayer(KisNodeSP node) { return qobject_cast<KisLayer*>(node.data()); }
KisImageBuilder_Result CSVSaver::encode(const QUrl &uri,const QString &filename) { int idx; int start, end; KisNodeSP node; QByteArray ba; KisKeyframeSP keyframe; QVector<CSVLayerRecord*> layers; KisImageAnimationInterface *animation = m_image->animationInterface(); //open the csv file for writing QFile f(uri.toLocalFile()); if (!f.open(QIODevice::WriteOnly)) { return KisImageBuilder_RESULT_NOT_LOCAL; } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); //DataStream instead of TextStream for correct line endings QDataStream stream(&f); QString path = filename; if (path.right(4).toUpper() == ".CSV") path = path.left(path.size() - 4); path.append(".frames"); //create directory QDir dir(path); if (!dir.exists()) { dir.mkpath("."); } //according to the QT docs, the slash is a universal directory separator path.append("/"); m_image->lock(); node = m_image->rootLayer()->firstChild(); //TODO: correct handling of the layer tree. //for now, only top level paint layers are saved idx = 0; while (node) { if (node->inherits("KisPaintLayer")) { KisPaintLayer* paintLayer = dynamic_cast<KisPaintLayer*>(node.data()); CSVLayerRecord* layerRecord = new CSVLayerRecord(); layers.prepend(layerRecord); //reverse order! layerRecord->name = paintLayer->name(); layerRecord->name.replace(QRegExp("[\"\\r\\n]"), "_"); if (layerRecord->name.isEmpty()) layerRecord->name= QString("Unnamed-%1").arg(idx); layerRecord->visible = (paintLayer->visible()) ? 1 : 0; layerRecord->density = (float)(paintLayer->opacity()) / OPACITY_OPAQUE_U8; layerRecord->blending = convertToBlending(paintLayer->compositeOpId()); layerRecord->layer = paintLayer; layerRecord->channel = paintLayer->projection()->keyframeChannel(); layerRecord->last = ""; layerRecord->frame = 0; idx++; } node = node->nextSibling(); } KisTimeRange range = animation->fullClipRange(); start = (range.isValid()) ? range.start() : 0; if (!range.isInfinite()) { end = range.end(); if (end < start) end = start; } else { //undefined length, searching for the last keyframe end = start; for (idx = 0; idx < layers.size(); idx++) { keyframe = layers.at(idx)->channel->lastKeyframe(); if ( (!keyframe.isNull()) && (keyframe->time() > end) ) end = keyframe->time(); } } //create temporary doc for exporting QScopedPointer<KisDocument> exportDoc(KisPart::instance()->createDocument()); createTempImage(exportDoc.data()); KisImageBuilder_Result retval= KisImageBuilder_RESULT_OK; if (!m_batchMode) { emit m_doc->statusBarMessage(i18n("Saving CSV file...")); emit m_doc->sigProgress(0); connect(m_doc, SIGNAL(sigProgressCanceled()), this, SLOT(cancel())); } int frame = start; int step = 0; do { qApp->processEvents(); if (m_stop) { retval = KisImageBuilder_RESULT_CANCEL; break; } switch(step) { case 0 : //first row if (f.write("UTF-8, TVPaint, \"CSV 1.0\"\r\n") < 0) { retval = KisImageBuilder_RESULT_FAILURE; } break; case 1 : //scene header names if (f.write("Project Name, Width, Height, Frame Count, Layer Count, Frame Rate, Pixel Aspect Ratio, Field Mode\r\n") < 0) { retval = KisImageBuilder_RESULT_FAILURE; } break; case 2 : //scene header values ba = QString("\"%1\", ").arg(m_image->objectName()).toUtf8(); if (f.write(ba.data()) < 0) { retval = KisImageBuilder_RESULT_FAILURE; break; } ba = QString("%1, %2, ").arg(m_image->width()).arg(m_image->height()).toUtf8(); if (f.write(ba.data()) < 0) { retval = KisImageBuilder_RESULT_FAILURE; break; } ba = QString("%1, %2, ").arg(end - start + 1).arg(layers.size()).toUtf8(); if (f.write(ba.data()) < 0) { retval = KisImageBuilder_RESULT_FAILURE; break; } //the framerate is an integer here ba = QString("%1, ").arg((double)(animation->framerate()),0,'f',6).toUtf8(); if (f.write(ba.data()) < 0) { retval = KisImageBuilder_RESULT_FAILURE; break; } ba = QString("%1, Progressive\r\n").arg((double)(m_image->xRes() / m_image->yRes()),0,'f',6).toUtf8(); if (f.write(ba.data()) < 0) { retval = KisImageBuilder_RESULT_FAILURE; break; } break; case 3 : //layer header values if (f.write("#Layers") < 0) { //Layers retval = KisImageBuilder_RESULT_FAILURE; break; } for (idx = 0; idx < layers.size(); idx++) { ba = QString(", \"%1\"").arg(layers.at(idx)->name).toUtf8(); if (f.write(ba.data()) < 0) break; } break; case 4 : if (f.write("\r\n#Density") < 0) { //Density retval = KisImageBuilder_RESULT_FAILURE; break; } for (idx = 0; idx < layers.size(); idx++) { ba = QString(", %1").arg((double)(layers.at(idx)->density), 0, 'f', 6).toUtf8(); if (f.write(ba.data()) < 0) break; } break; case 5 : if (f.write("\r\n#Blending") < 0) { //Blending retval = KisImageBuilder_RESULT_FAILURE; break; } for (idx = 0; idx < layers.size(); idx++) { ba = QString(", \"%1\"").arg(layers.at(idx)->blending).toUtf8(); if (f.write(ba.data()) < 0) break; } break; case 6 : if (f.write("\r\n#Visible") < 0) { //Visible retval = KisImageBuilder_RESULT_FAILURE; break; } for (idx = 0; idx < layers.size(); idx++) { ba = QString(", %1").arg(layers.at(idx)->visible).toUtf8(); if (f.write(ba.data()) < 0) break; } if (idx < layers.size()) { retval = KisImageBuilder_RESULT_FAILURE; } break; default : //frames if (frame > end) { if (f.write("\r\n") < 0) retval = KisImageBuilder_RESULT_FAILURE; step = 8; break; } ba = QString("\r\n#%1").arg(frame, 5, 10, QChar('0')).toUtf8(); if (f.write(ba.data()) < 0) { retval = KisImageBuilder_RESULT_FAILURE; break; } for (idx = 0; idx < layers.size(); idx++) { CSVLayerRecord *layer = layers.at(idx); keyframe = layer->channel->keyframeAt(frame); if (!keyframe.isNull()) { if (!m_batchMode) { emit m_doc->sigProgress(((frame - start) * layers.size() + idx) * 100 / ((end - start) * layers.size())); } retval = getLayer(layer, exportDoc.data(), keyframe, path, frame, idx); if (retval != KisImageBuilder_RESULT_OK) break; } ba = QString(", \"%1\"").arg(layer->last).toUtf8(); if (f.write(ba.data()) < 0) break; } if (idx < layers.size()) retval = KisImageBuilder_RESULT_FAILURE; frame++; step = 6; //keep step here break; } step++; } while((retval == KisImageBuilder_RESULT_OK) && (step < 8)); m_image->unlock(); qDeleteAll(layers); f.close(); if (!m_batchMode) { disconnect(m_doc, SIGNAL(sigProgressCanceled()), this, SLOT(cancel())); emit m_doc->sigProgress(100); emit m_doc->clearStatusBarMessage(); } QApplication::restoreOverrideCursor(); return retval; }