Skip to content

Commit

Permalink
Merge pull request #4681 from justburner/ClipboardImages
Browse files Browse the repository at this point in the history
Paste external clipboard images
  • Loading branch information
RodneyBaker committed Jan 1, 2023
2 parents 7f6dea6 + 2975e19 commit d2c95a8
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 33 deletions.
2 changes: 1 addition & 1 deletion toonz/sources/include/tools/rasterselection.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DVAPI RasterSelection final : public TSelection {
bool m_noAntialiasing;

private:
void pasteSelection(const RasterImageData *data);
bool pasteSelection(const RasterImageData *data);

public:
RasterSelection();
Expand Down
75 changes: 68 additions & 7 deletions toonz/sources/tnztools/rasterselection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "toonz/tframehandle.h"
#include "toonz/txsheethandle.h"
#include "toonz/tstageobject.h"
#include "toonzqt/gutil.h"

#include <QApplication>
#include <QClipboard>
Expand Down Expand Up @@ -1138,7 +1139,7 @@ void RasterSelection::cutSelection() {

//-----------------------------------------------------------------------------

void RasterSelection::pasteSelection(const RasterImageData *riData) {
bool RasterSelection::pasteSelection(const RasterImageData *riData) {
std::vector<TRectD> rect;
double currentDpiX, currentDpiY;
double dpiX, dpiY;
Expand All @@ -1152,18 +1153,18 @@ void RasterSelection::pasteSelection(const RasterImageData *riData) {
if (fullColorData) {
DVGui::error(QObject::tr(
"The copied selection cannot be pasted in the current drawing."));
return;
return false;
}
riData->getData(cmRas, dpiX, dpiY, rect, m_strokes, m_originalStrokes,
m_affine, m_currentImage->getPalette());
if (!cmRas) return;
if (!cmRas) return false;
m_floatingSelection = cmRas;
} else if (TRasterImageP ri = (TRasterImageP)m_currentImage) {
ri->getDpi(currentDpiX, currentDpiY);
TRasterP ras;
riData->getData(ras, dpiX, dpiY, rect, m_strokes, m_originalStrokes,
m_affine, ri->getPalette());
if (!ras) return;
if (!ras) return false;
if (TRasterCM32P rasCM = ras) {
TDimension dim = rasCM->getSize();
TRaster32P app = TRaster32P(dim.lx, dim.ly);
Expand All @@ -1178,6 +1179,7 @@ void RasterSelection::pasteSelection(const RasterImageData *riData) {
if (dpiX != 0 && dpiY != 0 && currentDpiX != 0 && currentDpiY != 0)
sc = TScale(currentDpiX / dpiX, currentDpiY / dpiY);
m_affine = m_affine * sc;
return true;
}

//-----------------------------------------------------------------------------
Expand All @@ -1195,6 +1197,10 @@ void RasterSelection::pasteSelection() {
return;
}

TXshLevel *xl = app->getCurrentLevel()->getLevel();
TXshSimpleLevel *sl = xl ? xl->getSimpleLevel() : nullptr;
int levelType = sl ? sl->getType() : NO_XSHLEVEL;

m_currentImage = image;
m_fid = tool->getCurrentFid();

Expand All @@ -1203,11 +1209,26 @@ void RasterSelection::pasteSelection() {
dynamic_cast<const RasterImageData *>(clipboard->mimeData());
const StrokesData *stData =
dynamic_cast<const StrokesData *>(clipboard->mimeData());
if (!riData && !stData) return;
QImage clipImage = clipboard->image();
if (!riData && !stData && clipImage.height() == 0) return;
if (isFloating()) pasteFloatingSelection();
selectNone();
m_isPastedSelection = true;
m_oldPalette = m_currentImage->getPalette()->clone();
if (!m_currentImageCell.getSimpleLevel()) {
const TXshCell &imageCell = TTool::getImageCell();

TImageP image =
imageCell.getImage(false, 1); // => See the onImageChanged() warning !

TToonzImageP ti = (TToonzImageP)image;
TRasterImageP ri = (TRasterImageP)image;
if (!ti && !ri) return;

makeCurrent();
setCurrentImage(image, imageCell);
}
if (m_currentImage->getPalette())
m_oldPalette = m_currentImage->getPalette()->clone();
if (stData) {
if (TToonzImageP ti = m_currentImage)
riData = stData->toToonzImageData(ti);
Expand All @@ -1227,8 +1248,48 @@ void RasterSelection::pasteSelection() {
}
}

if (clipImage.height() > 0 && (levelType == OVL_XSHLEVEL ||
m_currentImage->getType() == OVL_XSHLEVEL)) {
// An image was pasted from outside OpenToonz

// Set up variables
std::vector<TRectD> rects;
const std::vector<TStroke> strokes;
const std::vector<TStroke> originalStrokes;
TRasterImageP ri = m_currentImage;
TAffine aff;
TRasterP ras = rasterFromQImage(clipImage);
// center the image in the viewer
rects.push_back(TRectD(0.0 - clipImage.width() / 2,
0.0 - clipImage.height() / 2, clipImage.width() / 2,
clipImage.height() / 2));

TRectD r =
TRectD(0.0 - (clipImage.width() / 2), 0.0 - (clipImage.height() / 2),
clipImage.width() / 2, clipImage.height() / 2);
TRect box = getRaster(m_currentImage)->getBounds();
r *= convertRasterToWorld(box, m_currentImage);
if (!r.isEmpty()) {
TStroke stroke = getStrokeByRect(r);
if ((int)stroke.getControlPointCount() == 0) return;
m_strokes.push_back(stroke);
m_originalStrokes.push_back(stroke);
}
// pack up the data to send to the next pasteSelection
FullColorImageData *qimageData = new FullColorImageData();

qimageData->setData(ras, ri->getPalette(), 120.0, 120.0,
ri->getRaster()->getSize(), rects, m_strokes,
m_originalStrokes, aff);
setSelectionBbox(TRectD(0.0 - clipImage.width() / 2,
0.0 - clipImage.height() / 2, clipImage.width() / 2,
clipImage.height() / 2));

riData = qimageData;
}

if (!riData) return;
pasteSelection(riData);
if (!pasteSelection(riData)) return;

app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
notify();
Expand Down
8 changes: 7 additions & 1 deletion toonz/sources/tnztools/toolutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,13 +533,16 @@ void ToolUtils::TToolUndo::removeLevelAndFrameIfNeeded() const {
m_level->eraseFrame(m_frameId);
if (!m_isEditingLevel) {
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
TXshCell cell;
for (const TTool::CellOps &cellOps : m_cellsData) {
TXshCell cell;
if (cellOps.type == TTool::CellOps::ExistingToNew)
cell = xsh->getCell(cellOps.r0 - 1, m_col);
for (int r = cellOps.r0; r <= cellOps.r1; r++)
xsh->setCell(r, m_col, cell);
}
if (m_cellsData.size() < 1) {
xsh->setCell(m_row, m_col, cell);
}
}
if (m_createdLevel) {
// butta il livello
Expand Down Expand Up @@ -666,6 +669,9 @@ void ToolUtils::TRasterUndo::undo() const {

removeLevelAndFrameIfNeeded();

if (m_level) {
m_level->setDirtyFlag(true);
}
app->getCurrentXsheet()->notifyXsheetChanged();
notifyImageChanged();
}
Expand Down

0 comments on commit d2c95a8

Please sign in to comment.