[krita] /: [FEATURE] Add "convert to file layer" command to file layers.

Wolthera van Hövell tot Westerflier null at kde.org
Mon Oct 30 14:42:10 UTC 2017


Git commit bb3aaece7c2e541269994e62cdd4777e32f383f2 by Wolthera van Hövell tot Westerflier.
Committed on 30/10/2017 at 13:40.
Pushed by woltherav into branch 'master'.

[FEATURE] Add "convert to file layer" command to file layers.

This adds an action that can be triggered on any non referencing layer(so not file or clone layers).

This action will request a file name, and then save the layer(if a group layer, with everything in it)
into a seperate file. It will then replace the layer in the old with with a file layer referencing the
new file.

The idea behind this one is that if people's layer stacks become too complicated,
they can save out a section of it to a file layer, reducing the complexity of the document.

CCMAIL:Kimageshop at kde.org
Differential Revision: https://phabricator.kde.org/D8360

M  +12   -0    krita/krita.action
M  +2    -1    krita/krita4.xmlgui
M  +80   -0    libs/ui/kis_layer_manager.cc
M  +2    -0    libs/ui/kis_layer_manager.h
M  +4    -1    libs/ui/kis_node_manager.cpp
M  +1    -0    libs/widgets/kis_file_name_requester.cpp
M  +1    -0    plugins/dockers/defaultdockers/kis_layer_box.cpp

https://commits.kde.org/krita/bb3aaece7c2e541269994e62cdd4777e32f383f2

diff --git a/krita/krita.action b/krita/krita.action
index 3c302c1e66d..cbc3dfbe8c2 100644
--- a/krita/krita.action
+++ b/krita/krita.action
@@ -2610,6 +2610,18 @@
       <isCheckable>false</isCheckable>
       <statusTip></statusTip>
     </Action>
+    <Action name="convert_layer_to_file_layer">
+      <icon>fileLayer</icon>
+      <text>to &File Layer</text>
+      <whatsThis></whatsThis>
+      <toolTip>Saves out the layers into a new image and then references that image.</toolTip>
+      <iconText>Convert to File Layer</iconText>
+      <activationFlags>100000</activationFlags>
+      <activationConditions>0</activationConditions>
+      <shortcut></shortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
     <Action name="import_layer_from_file">
       <icon></icon>
       <text>I&mport Layer...</text>
diff --git a/krita/krita4.xmlgui b/krita/krita4.xmlgui
index 996bdb08aef..9b0513d01ce 100644
--- a/krita/krita4.xmlgui
+++ b/krita/krita4.xmlgui
@@ -2,7 +2,7 @@
 <kpartgui xmlns="http://www.kde.org/standards/kxmlgui/1.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 name="Krita"
-version="122"
+version="123"
 xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0  http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd">
   <MenuBar>
     <Menu name="file">
@@ -197,6 +197,7 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0  http://www.kde.org
         <Action name="convert_to_transparency_mask"/>
         <Action name="convert_to_filter_mask"/>
         <Action name="convert_to_selection_mask"/>
+        <Action name="convert_layer_to_file_layer"/>
         <Action name="convert_group_to_animated"/>
         <Action name="layercolorspaceconversion"/>
       </Menu>
diff --git a/libs/ui/kis_layer_manager.cc b/libs/ui/kis_layer_manager.cc
index 994e73c0101..d3c4cde16d4 100644
--- a/libs/ui/kis_layer_manager.cc
+++ b/libs/ui/kis_layer_manager.cc
@@ -435,6 +435,86 @@ void KisLayerManager::convertGroupToAnimated()
     m_commandsAdapter->endMacro();
 }
 
+void KisLayerManager::convertLayerToFileLayer(KisNodeSP source)
+{
+    KisImageSP image = m_view->image();
+    if (!image) return;
+
+    QStringList listMimeFilter = KisImportExportManager::mimeFilter(KisImportExportManager::Export);
+
+    KoDialog dlg;
+    QWidget *page = new QWidget(&dlg);
+    dlg.setMainWidget(page);
+    QBoxLayout *layout = new QVBoxLayout(page);
+    dlg.setWindowTitle(i18n("Save layers to..."));
+    QLabel *lbl = new QLabel(i18n("Choose the location where the layer will be saved to. The new file layer will then reference this location."));
+    lbl->setWordWrap(true);
+    layout->addWidget(lbl);
+    KisFileNameRequester *urlRequester = new KisFileNameRequester(page);
+    urlRequester->setMode(KoFileDialog::SaveFile);
+    urlRequester->setMimeTypeFilters(listMimeFilter);
+    urlRequester->setFileName(m_view->document()->url().toLocalFile());
+    if (m_view->document()->url().isLocalFile()) {
+        QFileInfo location = QFileInfo(m_view->document()->url().toLocalFile()).baseName();
+        location.setFile(location.dir(), location.baseName()+"_"+ source->name()+".kra");
+        urlRequester->setFileName(location.absoluteFilePath());
+    } else {
+        const QFileInfo location = QFileInfo(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
+        const QString proposedFileName = QDir(location.absoluteFilePath()).absoluteFilePath(source->name() + ".kra");
+        urlRequester->setFileName(proposedFileName);
+    }
+
+    layout->addWidget(urlRequester);
+    if (!dlg.exec()) return;
+
+    QString path = urlRequester->fileName();
+
+    if (path.isEmpty()) return;
+
+    QFileInfo f(path);
+
+    QString mimeType= KisMimeDatabase::mimeTypeForFile(f.fileName());
+    if (mimeType.isEmpty()) {
+        mimeType = "image/png";
+    }
+    QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
+
+    QRect bounds = source->exactBounds();
+
+    KisImageSP dst = new KisImage(doc->createUndoStore(),
+                                  image->width(),
+                                  image->height(),
+                                  image->projection()->compositionSourceColorSpace(),
+                                  source->name());
+    dst->setResolution(image->xRes(), image->yRes());
+    doc->setFileBatchMode(false);
+    doc->setCurrentImage(dst);
+    KisNodeSP node = source->clone();
+    dst->addNode(node);
+    dst->initialRefreshGraph();
+    dst->cropImage(bounds);
+    dst->waitForDone();
+
+    bool r = doc->exportDocumentSync(QUrl::fromLocalFile(path), mimeType.toLatin1());
+    if (!r) {
+        qDebug()<< "Path:"<<path;
+        qWarning() << doc->errorMessage();
+    } else {
+        QString basePath = QFileInfo(m_view->document()->url().toLocalFile()).absolutePath();
+        QString relativePath = QDir(basePath).relativeFilePath(path);
+        KisFileLayer *fileLayer = new KisFileLayer(image, basePath, relativePath, KisFileLayer::None, source->name(), OPACITY_OPAQUE_U8);
+        fileLayer->setX(bounds.x());
+        fileLayer->setY(bounds.y());
+        KisNodeSP dstParent = source->parent();
+        KisNodeSP dstAboveThis = source->prevSibling();
+        m_commandsAdapter->beginMacro(kundo2_i18n("Convert to a file layer"));
+        m_commandsAdapter->removeNode(source);
+        m_commandsAdapter->addNode(fileLayer, dstParent, dstAboveThis);
+        m_commandsAdapter->endMacro();
+    }
+    doc->closeUrl(false);
+}
+
 void KisLayerManager::adjustLayerPosition(KisNodeSP node, KisNodeSP activeNode, KisNodeSP &parent, KisNodeSP &above)
 {
     Q_ASSERT(activeNode);
diff --git a/libs/ui/kis_layer_manager.h b/libs/ui/kis_layer_manager.h
index 15b8b3ef375..17f9d9cdaf9 100644
--- a/libs/ui/kis_layer_manager.h
+++ b/libs/ui/kis_layer_manager.h
@@ -91,6 +91,8 @@ private Q_SLOTS:
     void convertNodeToPaintLayer(KisNodeSP source);
     void convertGroupToAnimated();
 
+    void convertLayerToFileLayer(KisNodeSP source);
+
     KisLayerSP addLayer(KisNodeSP activeNode);
     void addGroupLayer(KisNodeSP activeNode);
 
diff --git a/libs/ui/kis_node_manager.cpp b/libs/ui/kis_node_manager.cpp
index e055b70e5d8..0f70ccc11cf 100644
--- a/libs/ui/kis_node_manager.cpp
+++ b/libs/ui/kis_node_manager.cpp
@@ -346,6 +346,8 @@ void KisNodeManager::setup(KActionCollection * actionCollection, KisActionManage
 
     CONVERT_NODE_ACTION("convert_to_animated", "animated");
 
+    CONVERT_NODE_ACTION_2("convert_layer_to_file_layer", "KisFileLayer", QStringList()<< "KisFileLayer" << "KisCloneLayer");
+
     connect(&m_d->nodeConversionSignalMapper, SIGNAL(mapped(const QString &)),
             this, SLOT(convertNode(const QString &)));
 
@@ -589,7 +591,8 @@ void KisNodeManager::convertNode(const QString &nodeType)
 
         m_d->commandsAdapter.removeNode(activeNode);
         m_d->commandsAdapter.endMacro();
-
+    } else if (nodeType == "KisFileLayer") {
+            m_d->layerManager.convertLayerToFileLayer(activeNode);
     } else {
         warnKrita << "Unsupported node conversion type:" << nodeType;
     }
diff --git a/libs/widgets/kis_file_name_requester.cpp b/libs/widgets/kis_file_name_requester.cpp
index 966cc469995..3942e80a1f3 100644
--- a/libs/widgets/kis_file_name_requester.cpp
+++ b/libs/widgets/kis_file_name_requester.cpp
@@ -49,6 +49,7 @@ void KisFileNameRequester::setStartDir(const QString &path)
 void KisFileNameRequester::setFileName(const QString &path)
 {
     m_ui->txtFileName->setText(path);
+    m_basePath = path;
     emit fileSelected(path);
 }
 
diff --git a/plugins/dockers/defaultdockers/kis_layer_box.cpp b/plugins/dockers/defaultdockers/kis_layer_box.cpp
index e0664604ac8..57fd8b7ad84 100644
--- a/plugins/dockers/defaultdockers/kis_layer_box.cpp
+++ b/plugins/dockers/defaultdockers/kis_layer_box.cpp
@@ -621,6 +621,7 @@ void KisLayerBox::slotContextMenuRequested(const QPoint &pos, const QModelIndex
                 addActionToMenu(convertToMenu, "convert_to_transparency_mask");
                 addActionToMenu(convertToMenu, "convert_to_filter_mask");
                 addActionToMenu(convertToMenu, "convert_to_selection_mask");
+                addActionToMenu(convertToMenu, "convert_layer_to_file_layer");
 
                 QMenu *splitAlphaMenu = menu.addMenu(i18n("S&plit Alpha"));
                 addActionToMenu(splitAlphaMenu, "split_alpha_into_mask");



More information about the kimageshop mailing list