File indexing completed on 2024-05-19 04:28:58
0001 /* 0002 * SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_import_catcher.h" 0008 #include <kis_debug.h> 0009 0010 #include <klocalizedstring.h> 0011 #include <QFileInfo> 0012 0013 #include <KisImportExportManager.h> 0014 0015 #include "kis_node_manager.h" 0016 #include "kis_count_visitor.h" 0017 #include "KisViewManager.h" 0018 #include "KisDocument.h" 0019 #include "kis_image.h" 0020 #include "kis_layer.h" 0021 #include "kis_painter.h" 0022 #include "kis_selection.h" 0023 #include "kis_node_commands_adapter.h" 0024 #include "kis_group_layer.h" 0025 #include "kis_progress_widget.h" 0026 #include "kis_config.h" 0027 #include "KisPart.h" 0028 #include "kis_shape_layer.h" 0029 0030 struct KisImportCatcher::Private 0031 { 0032 public: 0033 KisDocument* doc; 0034 KisViewManager* view; 0035 QString path; 0036 QString layerType; 0037 int numLayersImported; 0038 0039 QString prettyLayerName(QString layerName) const; 0040 void importAsPaintLayer(KisPaintDeviceSP device, QString layerName); 0041 void importShapeLayer(KisShapeLayerSP shapeLayer); 0042 }; 0043 0044 QString KisImportCatcher::Private::prettyLayerName(QString layerName) const 0045 { 0046 QString name = QFileInfo(path).fileName(); 0047 QString fileName = !name.isEmpty() ? name : path; 0048 return (layerName.isEmpty() || layerName == "Background") ? fileName : layerName; 0049 } 0050 0051 void KisImportCatcher::Private::importAsPaintLayer(KisPaintDeviceSP device, QString layerName) 0052 { 0053 KisLayerSP newLayer = new KisPaintLayer(view->image(), 0054 layerName, 0055 OPACITY_OPAQUE_U8, 0056 device); 0057 0058 KisNodeSP parent = nullptr; 0059 KisLayerSP currentActiveLayer = view->activeLayer(); 0060 0061 if (currentActiveLayer) { 0062 parent = currentActiveLayer->parent(); 0063 } 0064 0065 if (parent.isNull()) { 0066 parent = view->image()->rootLayer(); 0067 } 0068 0069 KisNodeCommandsAdapter adapter(view); 0070 adapter.addNode(newLayer, parent, currentActiveLayer); 0071 } 0072 0073 void KisImportCatcher::Private::importShapeLayer(KisShapeLayerSP shapeLayer) 0074 { 0075 KisNodeSP parent = nullptr; 0076 KisLayerSP currentActiveLayer = view->activeLayer(); 0077 0078 if (currentActiveLayer) { 0079 parent = currentActiveLayer->parent(); 0080 } 0081 0082 if (parent.isNull()) { 0083 parent = view->image()->rootLayer(); 0084 } 0085 0086 KisNodeCommandsAdapter adapter(view); 0087 adapter.addNode(shapeLayer, parent, currentActiveLayer); 0088 } 0089 0090 KisImportCatcher::KisImportCatcher(const QString &path, KisViewManager *view, const QString &layerType) 0091 : m_d(new Private) 0092 { 0093 m_d->doc = KisPart::instance()->createDocument(); 0094 m_d->view = view; 0095 m_d->path = path; 0096 m_d->layerType = layerType; 0097 m_d->numLayersImported = 0; 0098 0099 connect(m_d->doc, SIGNAL(sigLoadingFinished()), this, SLOT(slotLoadingFinished())); 0100 bool result = m_d->doc->openPath(path, KisDocument::DontAddToRecent); 0101 0102 if (!result) { 0103 deleteMyself(); 0104 } 0105 } 0106 0107 void KisImportCatcher::slotLoadingFinished() 0108 { 0109 KisImageWSP importedImage = m_d->doc->image(); 0110 importedImage->waitForDone(); 0111 0112 if (importedImage && importedImage->bounds().isValid()) { 0113 if (m_d->layerType == "KisPaintLayer") { 0114 QStringList list; 0115 list << "KisLayer"; 0116 KoProperties props; 0117 0118 Q_FOREACH(KisNodeSP node, importedImage->rootLayer()->childNodes(list, props)) { 0119 // we need to pass a copied device to make sure it is not reset 0120 // on image's destruction 0121 KisPaintDeviceSP dev = new KisPaintDevice(*node->projection()); 0122 adaptClipToImageColorSpace(dev, m_d->view->image()); 0123 m_d->importAsPaintLayer(dev, m_d->prettyLayerName(node->name())); 0124 m_d->numLayersImported++; 0125 } 0126 } 0127 else if (m_d->layerType == "KisShapeLayer") { 0128 KisShapeLayerSP shapeLayer = new KisShapeLayer(m_d->view->document()->shapeController(), 0129 m_d->view->image().data(), 0130 m_d->prettyLayerName(QString()), 0131 OPACITY_OPAQUE_U8); 0132 KisShapeLayerSP imported = dynamic_cast<KisShapeLayer*>(importedImage->rootLayer()->firstChild().data()); 0133 0134 const QTransform thisInvertedTransform = shapeLayer->absoluteTransformation().inverted(); 0135 0136 Q_FOREACH (KoShape *shape, imported->shapes()) { 0137 KoShape *clonedShape = shape->cloneShape(); 0138 clonedShape->setTransformation(shape->absoluteTransformation() * thisInvertedTransform); 0139 shapeLayer->addShape(clonedShape); 0140 } 0141 m_d->importShapeLayer(shapeLayer); 0142 m_d->numLayersImported++; 0143 } 0144 else { 0145 KisPaintDeviceSP dev = new KisPaintDevice(*importedImage->projection()); 0146 m_d->view->nodeManager()->createNode(m_d->layerType, false, dev); 0147 m_d->numLayersImported++; 0148 } 0149 } 0150 0151 deleteMyself(); 0152 } 0153 0154 int KisImportCatcher::numLayersImported() const 0155 { 0156 return m_d->numLayersImported; 0157 } 0158 0159 void KisImportCatcher::deleteMyself() 0160 { 0161 m_d->doc->deleteLater(); 0162 deleteLater(); 0163 } 0164 0165 KisImportCatcher::~KisImportCatcher() 0166 { 0167 delete m_d; 0168 } 0169 0170 void KisImportCatcher::adaptClipToImageColorSpace(KisPaintDeviceSP dev, KisImageSP image) 0171 { 0172 KisConfig cfg(true); 0173 if (cfg.convertToImageColorspaceOnImport() && *dev->colorSpace() != *image->colorSpace()) { 0174 /// XXX: do we need intent here? 0175 dev->convertTo(image->colorSpace()); 0176 } 0177 } 0178