Commit ef76c7df authored by Dmitrii Utkin's avatar Dmitrii Utkin Committed by Dmitrii Utkin

Enhancements in reference image tool, optimized loading of images from clipboard

parent c6a8935d
......@@ -185,6 +185,7 @@ options_configure_toolbars=none
paintops=none
paste_at=none
paste_new=Ctrl+Shift+N
paste_as_reference=Ctrl+Shift+R
patterns=none
preserve_alpha=none
previous_favorite_preset=.
......
......@@ -53,6 +53,7 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org
<Action name="edit_paste"/>
<Action name="paste_at"/>
<Action name="paste_new"/>
<Action name="paste_as_reference"/>
<Action name="clear"/>
<Action name="fill_selection_foreground_color"/>
<Action name="fill_selection_background_color"/>
......
......@@ -393,6 +393,18 @@
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="paste_as_reference">
<icon></icon>
<text>Paste as R&amp;eference Image</text>
<whatsThis></whatsThis>
<toolTip>Paste as Reference Image</toolTip>
<iconText>Paste as Reference Image</iconText>
<activationFlags>1</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>Ctrl+Shift+R</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="clear">
<icon>edit-clear</icon>
<text>C&amp;lear</text>
......
......@@ -279,6 +279,7 @@ set(kritaui_LIB_SRCS
utils/kis_document_aware_spin_box_unit_manager.cpp
utils/KisSpinBoxSplineUnitConverter.cpp
utils/KisClipboardUtil.cpp
input/kis_input_manager.cpp
input/kis_input_manager_p.cpp
......
......@@ -35,6 +35,7 @@
#include <SvgUtil.h>
#include <libs/flake/svg/parsers/SvgTransformParser.h>
#include <libs/brush/kis_qimage_pyramid.h>
#include <utils/KisClipboardUtil.h>
struct KisReferenceImage::Private {
// Filename within .kra (for embedding)
......@@ -57,7 +58,7 @@ struct KisReferenceImage::Private {
}
bool loadFromClipboard() {
image = QApplication::clipboard()->image();
image = KisClipboardUtil::getImageFromClipboard();
return !image.isNull();
}
......@@ -151,23 +152,18 @@ KisReferenceImage * KisReferenceImage::fromFile(const QString &filename, const K
return reference;
}
KisReferenceImage* KisReferenceImage::fromClipboard(const KisCoordinatesConverter &converter, QWidget *parent)
KisReferenceImage *KisReferenceImage::fromClipboard(const KisCoordinatesConverter &converter)
{
KisReferenceImage *reference = new KisReferenceImage();
bool ok = reference->d->loadFromClipboard();
if(ok){
if (ok) {
QRect r = QRect(QPoint(), reference->d->image.size());
QSizeF size = converter.imageToDocument(r).size();
reference->setSize(size);
} else {
delete reference;
if(parent){
QMessageBox::critical(parent, i18nc("@title:window", "Krita"), i18n("Could not load image from clipboard."));
}
return nullptr;
reference = nullptr;
}
return reference;
......
......@@ -63,7 +63,7 @@ public:
* @return reference image or null if one could not be loaded
*/
static KisReferenceImage * fromFile(const QString &filename, const KisCoordinatesConverter &converter, QWidget *parent /*= nullptr*/);
static KisReferenceImage * fromClipboard(const KisCoordinatesConverter &converter, QWidget *parent);
static KisReferenceImage * fromClipboard(const KisCoordinatesConverter &converter);
void setSaturation(qreal saturation);
qreal saturation() const;
......
......@@ -26,6 +26,7 @@
#include <KisMainWindow.h>
#include <KisDocument.h>
#include <KisPart.h>
#include <KisReferenceImagesLayer.h>
#include <KoPathShape.h>
#include <KoShapeController.h>
#include <KoShapeRegistry.h>
......@@ -390,6 +391,20 @@ void KisCopyMergedActionFactory::run(KisViewManager *view)
endAction(ap, KisOperationConfiguration(id()).toXML());
}
void KisPasteReferenceActionFactory::run(KisViewManager *viewManager)
{
KisCanvas2 *canvasBase = viewManager->canvasBase();
if (!canvasBase) return;
KisReferenceImage* reference = KisReferenceImage::fromClipboard(*canvasBase->coordinatesConverter());
if (!reference) return;
KisDocument *doc = viewManager->document();
doc->addCommand(KisReferenceImagesLayer::addReferenceImages(doc, {reference}));
KoToolManager::instance()->switchToolRequested("ToolReferenceImages");
}
void KisPasteNewActionFactory::run(KisViewManager *viewManager)
{
Q_UNUSED(viewManager);
......
......@@ -89,6 +89,11 @@ struct KRITAUI_EXPORT KisCopyMergedActionFactory : public KisNoParameterActionFa
void run(KisViewManager *view) override;
};
struct KRITAUI_EXPORT KisPasteReferenceActionFactory : public KisNoParameterActionFactory {
KisPasteReferenceActionFactory() : KisNoParameterActionFactory("paste-reference-ui-action") {}
void run(KisViewManager *view) override;
};
struct KRITAUI_EXPORT KisPasteNewActionFactory : public KisNoParameterActionFactory {
KisPasteNewActionFactory() : KisNoParameterActionFactory("paste-new-ui-action") {}
void run(KisViewManager *view) override;
......
......@@ -46,6 +46,7 @@
#include <kis_node.h>
#include <kis_image.h>
#include <kis_time_range.h>
#include <utils/KisClipboardUtil.h>
// local
#include "kis_config.h"
......@@ -276,71 +277,7 @@ KisPaintDeviceSP KisClipboard::clip(const QRect &imageBounds, bool showPopup, Ki
if (!clip) {
QStringList formats = cb->mimeData()->formats();
QMap<int, QImage> qimages;
Q_FOREACH(const QString format, formats) {
// qDebug() << "Format" << format;
QImage image;
if (format.startsWith("image")) {
int priority = -1;
QByteArray ba = cb->mimeData()->data(format);
// qDebug() << "data" << ba.size() << "mime" << KisMimeDatabase::mimeTypeForData(ba);
if (ba.isEmpty()) {
continue;
}
QString qimageioFormat;
if (format == "image/png") {
qimageioFormat = "PNG";
priority = 0;
}
else if (format == "image/tiff") {
qimageioFormat = "TIFF";
priority = 1;
}
else if (format == "image/bmp"
|| format == "image/x-bmp"
|| format == "image/x-MS-bmp"
|| format == "image/x-win-bitmap") {
qimageioFormat = "BMP";
priority = 2;
}
else if (format == "image/jpeg") {
qimageioFormat = "JPG";
priority = 3;
}
if (!qimageioFormat.isEmpty()) {
image.loadFromData(ba, qimageioFormat.toLatin1());
}
if (!image.isNull()) {
// qDebug() << "Loaded image succesfully" << image.format() << image.hasAlphaChannel();
qimages[priority] = image;
}
// else {
// qDebug() << "Could not load image of type" << format;
// }
}
}
QImage qimage = cb->image();
for(int i = 0; i < 4; i++) {
if (qimages.contains(i)) {
qimage = qimages[i];
break;
}
}
// qDebug() << "Final QImage" << qimage.format() << qimage.hasAlphaChannel();
QImage qimage = KisClipboardUtil::getImageFromClipboard();
if (qimage.isNull()) {
return KisPaintDeviceSP(0);
......
......@@ -141,6 +141,9 @@ void KisSelectionManager::setup(KisActionManager* actionManager)
m_pasteAt = actionManager->createAction("paste_at");
connect(m_pasteAt, SIGNAL(triggered()), this, SLOT(pasteAt()));
m_pasteAsReference = actionManager->createAction("paste_as_reference");
connect(m_pasteAsReference, SIGNAL(triggered()), this, SLOT(pasteAsReference()));
m_copyMerged = actionManager->createAction("copy_merged");
connect(m_copyMerged, SIGNAL(triggered()), this, SLOT(copyMerged()));
......@@ -327,6 +330,7 @@ void KisSelectionManager::updateGUI()
m_pasteAt->setEnabled(havePixelsInClipboard || haveShapesInClipboard);
// FIXME: how about pasting shapes?
m_pasteNew->setEnabled(havePixelsInClipboard);
m_pasteAsReference->setEnabled(haveDevice);
m_selectAll->setEnabled(true);
m_deselect->setEnabled(canDeselect);
......@@ -394,6 +398,12 @@ void KisSelectionManager::pasteAt()
factory.run(true, m_view);
}
void KisSelectionManager::pasteAsReference()
{
KisPasteReferenceActionFactory factory;
factory.run(m_view);
}
void KisSelectionManager::pasteNew()
{
KisPasteNewActionFactory factory;
......
......@@ -85,6 +85,7 @@ public Q_SLOTS:
void paste();
void pasteNew();
void pasteAt();
void pasteAsReference();
void cutToNewLayer();
void selectAll();
void deselect();
......@@ -149,6 +150,7 @@ private:
KisAction *m_cut;
KisAction *m_paste;
KisAction *m_pasteAt;
KisAction *m_pasteAsReference;
KisAction *m_pasteNew;
KisAction *m_cutToNewLayer;
KisAction *m_selectAll;
......
/*
* Copyright (c) 2019 Dmitrii Utkin <loentar@gmail.com>
*
* 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 "KisClipboardUtil.h"
#include <QApplication>
#include <QClipboard>
#include <QMimeData>
#include <QImage>
#include <QList>
#include <QSet>
#include <QPair>
namespace KisClipboardUtil {
QImage getImageFromClipboard()
{
static const QList<QPair<QSet<QString>, QString>> supportedFormats = {
{{"image/png"}, "PNG"},
{{"image/tiff"}, "TIFF"},
{{"image/bmp", "image/x-bmp", "image/x-MS-bmp", "image/x-win-bitmap"}, "BMP"},
{{"image/jpeg"}, "JPG"}
};
QClipboard *clipboard = QApplication::clipboard();
QImage image = clipboard->image();
if (!image.isNull()) {
return image;
}
const QSet<QString> &clipboardFormats = clipboard->mimeData()->formats().toSet();
Q_FOREACH (const auto &supportedFormat, supportedFormats) {
const auto& intersection = supportedFormat.first & clipboardFormats;
if (intersection.isEmpty()) {
continue;
}
const QString& format = *intersection.constBegin();
const QByteArray &imageData = clipboard->mimeData()->data(format);
if (imageData.isEmpty()) {
continue;
}
if (image.loadFromData(imageData, supportedFormat.second.toLatin1())) {
break;
}
}
return image;
}
}
\ No newline at end of file
/*
* Copyright (c) 2019 Dmitrii Utkin <loentar@gmail.com>
*
* 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.
*/
#ifndef KIS_CLIPBOARD_UTIL_H
#define KIS_CLIPBOARD_UTIL_H
#include <kritaui_export.h>
class QImage;
namespace KisClipboardUtil {
/**
* load an image from clipboard handling different supported formats
* @return image
*/
KRITAUI_EXPORT QImage getImageFromClipboard();
}
#endif //KIS_CLIPBOARD_UTIL_H
......@@ -114,7 +114,7 @@ void ToolReferenceImages::pasteReferenceImage()
KisCanvas2* kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
KIS_ASSERT_RECOVER_RETURN(kisCanvas)
KisReferenceImage* reference = KisReferenceImage::fromClipboard(*kisCanvas->coordinatesConverter(), canvas()->canvasWidget());
KisReferenceImage* reference = KisReferenceImage::fromClipboard(*kisCanvas->coordinatesConverter());
if(reference) {
KisDocument *doc = document();
doc->addCommand(KisReferenceImagesLayer::addReferenceImages(doc, {reference}));
......
......@@ -82,14 +82,12 @@ ToolReferenceImagesWidget::ToolReferenceImagesWidget(ToolReferenceImages *tool,
d->ui->bnSave->setToolTip(i18n("Export Reference Images Set"));
d->ui->bnSave->setIcon(KisIconUtils::loadIcon("document-save"));
slotCheckClipboardContents();
d->ui->bnPasteReferenceImage->setToolTip(i18n("Paste Reference Image From System Clipboard"));
d->ui->bnPasteReferenceImage->setIcon(KisIconUtils::loadIcon("edit-paste"));
connect(d->ui->bnAddReferenceImage, SIGNAL(clicked()), tool, SLOT(addReferenceImage()));
connect(d->ui->bnPasteReferenceImage, SIGNAL(clicked()), tool, SLOT(pasteReferenceImage()));
connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotCheckClipboardContents()));
connect(d->ui->bnDelete, SIGNAL(clicked()), tool, SLOT(removeAllReferenceImages()));
connect(d->ui->bnSave, SIGNAL(clicked()), tool, SLOT(saveReferenceImages()));
......@@ -156,10 +154,6 @@ void ToolReferenceImagesWidget::selectionChanged(KoSelection *selection)
updateVisibility(anySelected);
}
void ToolReferenceImagesWidget::slotCheckClipboardContents() {
d->ui->bnPasteReferenceImage->setEnabled(!QApplication::clipboard()->image().isNull());
}
void ToolReferenceImagesWidget::slotKeepAspectChanged()
{
KoSelection *selection = d->tool->koSelection();
......
......@@ -45,7 +45,6 @@ private Q_SLOTS:
void slotSaturationSliderChanged(qreal);
void slotKeepAspectChanged();
void slotSaveLocationChanged(int index);
void slotCheckClipboardContents();
private:
struct Private;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment