More paste improvements (#248)

* Some fixes

* more little fixes

* Make vector selections work too
This commit is contained in:
Jeremy Bullock 2020-09-28 21:28:52 -06:00 committed by GitHub
parent 967ad6de14
commit dff5b5fdcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 213 additions and 29 deletions

View file

@ -278,7 +278,7 @@ TPalette::~TPalette() {
TPalette *TPalette::clone() const { TPalette *TPalette::clone() const {
TPalette *palette = new TPalette; TPalette *palette = new TPalette;
palette->assign(this); if (this && this->m_styles.size() > 0) palette->assign(this);
return palette; return palette;
} }

View file

@ -56,7 +56,7 @@ class DVAPI RasterSelection final : public TSelection {
bool m_noAntialiasing; bool m_noAntialiasing;
private: private:
void pasteSelection(const RasterImageData *data); bool pasteSelection(const RasterImageData *data);
public: public:
RasterSelection(); RasterSelection();

View file

@ -1024,6 +1024,19 @@ void RasterSelection::makeFloating() {
void RasterSelection::pasteFloatingSelection() { void RasterSelection::pasteFloatingSelection() {
if (!isFloating()) return; if (!isFloating()) return;
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);
}
assert(m_transformationCount != -1 && m_transformationCount != -2); assert(m_transformationCount != -1 && m_transformationCount != -2);
@ -1126,7 +1139,7 @@ void RasterSelection::cutSelection() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void RasterSelection::pasteSelection(const RasterImageData *riData) { bool RasterSelection::pasteSelection(const RasterImageData *riData) {
std::vector<TRectD> rect; std::vector<TRectD> rect;
double currentDpiX, currentDpiY; double currentDpiX, currentDpiY;
double dpiX, dpiY; double dpiX, dpiY;
@ -1140,18 +1153,18 @@ void RasterSelection::pasteSelection(const RasterImageData *riData) {
if (fullColorData) { if (fullColorData) {
DVGui::error(QObject::tr( DVGui::error(QObject::tr(
"The copied selection cannot be pasted in the current drawing.")); "The copied selection cannot be pasted in the current drawing."));
return; return false;
} }
riData->getData(cmRas, dpiX, dpiY, rect, m_strokes, m_originalStrokes, riData->getData(cmRas, dpiX, dpiY, rect, m_strokes, m_originalStrokes,
m_affine, m_currentImage->getPalette()); m_affine, m_currentImage->getPalette());
if (!cmRas) return; if (!cmRas) return false;
m_floatingSelection = cmRas; m_floatingSelection = cmRas;
} else if (TRasterImageP ri = (TRasterImageP)m_currentImage) { } else if (TRasterImageP ri = (TRasterImageP)m_currentImage) {
ri->getDpi(currentDpiX, currentDpiY); ri->getDpi(currentDpiX, currentDpiY);
TRasterP ras; TRasterP ras;
riData->getData(ras, dpiX, dpiY, rect, m_strokes, m_originalStrokes, riData->getData(ras, dpiX, dpiY, rect, m_strokes, m_originalStrokes,
m_affine, ri->getPalette()); m_affine, ri->getPalette());
if (!ras) return; if (!ras) return false;
if (TRasterCM32P rasCM = ras) { if (TRasterCM32P rasCM = ras) {
TDimension dim = rasCM->getSize(); TDimension dim = rasCM->getSize();
TRaster32P app = TRaster32P(dim.lx, dim.ly); TRaster32P app = TRaster32P(dim.lx, dim.ly);
@ -1166,6 +1179,7 @@ void RasterSelection::pasteSelection(const RasterImageData *riData) {
if (dpiX != 0 && dpiY != 0 && currentDpiX != 0 && currentDpiY != 0) if (dpiX != 0 && dpiY != 0 && currentDpiX != 0 && currentDpiY != 0)
sc = TScale(currentDpiX / dpiX, currentDpiY / dpiY); sc = TScale(currentDpiX / dpiX, currentDpiY / dpiY);
m_affine = m_affine * sc; m_affine = m_affine * sc;
return true;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1177,6 +1191,10 @@ void RasterSelection::pasteSelection() {
if (!image) return; if (!image) return;
TXshLevel *xl = app->getCurrentLevel()->getLevel();
TXshSimpleLevel *sl = xl ? xl->getSimpleLevel() : 0;
int levelType = sl ? sl->getType() : NO_XSHLEVEL;
if (!isEditable()) { if (!isEditable()) {
DVGui::error( DVGui::error(
QObject::tr("The selection cannot be pasted. It is not editable.")); QObject::tr("The selection cannot be pasted. It is not editable."));
@ -1196,8 +1214,27 @@ void RasterSelection::pasteSelection() {
if (isFloating()) pasteFloatingSelection(); if (isFloating()) pasteFloatingSelection();
selectNone(); selectNone();
m_isPastedSelection = true; m_isPastedSelection = true;
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()) if (m_currentImage->getPalette())
m_oldPalette = m_currentImage->getPalette()->clone(); m_oldPalette = m_currentImage->getPalette()->clone();
if (!m_oldPalette)
m_oldPalette =
app->getPaletteController()->getDefaultPalette(sl->getType())->clone();
if (!m_currentImage->getPalette())
m_currentImage->setPalette(
app->getPaletteController()->getDefaultPalette(sl->getType())->clone());
if (stData) { if (stData) {
if (TToonzImageP ti = m_currentImage) if (TToonzImageP ti = m_currentImage)
riData = stData->toToonzImageData(ti); riData = stData->toToonzImageData(ti);
@ -1217,7 +1254,8 @@ void RasterSelection::pasteSelection() {
} }
} }
if (clipImage.height() > 0 && m_currentImage->getType() == OVL_XSHLEVEL) { if (clipImage.height() > 0 && (levelType == OVL_XSHLEVEL ||
m_currentImage->getType() == OVL_XSHLEVEL)) {
// An image was pasted from outside Tahoma // An image was pasted from outside Tahoma
// Set up variables // Set up variables
@ -1257,7 +1295,7 @@ void RasterSelection::pasteSelection() {
} }
if (!riData) return; if (!riData) return;
pasteSelection(riData); if (!pasteSelection(riData)) return;
app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged(); app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
notify(); notify();

View file

@ -252,7 +252,10 @@ public:
TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged(); TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
clipboard->setMimeData(data, QClipboard::Clipboard); clipboard->setMimeData(data, QClipboard::Clipboard);
TTool::getApplication()
->getPaletteController()
->getCurrentLevelPalette()
->notifyPaletteChanged();
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged(); TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
notifyImageChanged(); notifyImageChanged();
} }

View file

@ -52,6 +52,8 @@
#include "toonz/tstageobjecttree.h" #include "toonz/tstageobjecttree.h"
#include "toonz/stage.h" #include "toonz/stage.h"
#include "vectorizerpopup.h" #include "vectorizerpopup.h"
#include "tools/rasterselection.h"
#include "tools/strokeselection.h"
// TnzCore includes // TnzCore includes
#include "timagecache.h" #include "timagecache.h"
@ -706,6 +708,9 @@ bool pasteRasterImageInCellWithoutUndo(int row, int col,
sl = cell.getSimpleLevel(); sl = cell.getSimpleLevel();
fid = cell.getFrameId(); fid = cell.getFrameId();
img = cell.getImage(true); img = cell.getImage(true);
if (!img->getPalette()) {
img->setPalette(sl->getPalette());
}
TRasterP ras; TRasterP ras;
TRasterP outRas; TRasterP outRas;
double imgDpiX, imgDpiY; double imgDpiX, imgDpiY;
@ -1871,15 +1876,52 @@ void TCellSelection::pasteCells() {
xl->getPath().getFrame() != TFrameId::NO_FRAME)) xl->getPath().getFrame() != TFrameId::NO_FRAME))
img = cell.getImage(false); img = cell.getImage(false);
} }
if (!initUndo) {
initUndo = true;
TUndoManager::manager()->beginBlock();
}
RasterImageData *rasterImageData = 0; RasterImageData *rasterImageData = 0;
if (TToonzImageP ti = img) { if (TToonzImageP ti = img) {
TXshSimpleLevel* sl = xsh->getCell(r0, c0).getSimpleLevel();
if (!sl) sl = xsh->getCell(r0 - 1, c0).getSimpleLevel();
assert(sl);
ToolHandle* toolHandle = TApp::instance()->getCurrentTool();
TXshCell currentCell = xsh->getCell(r0, c0);
if (!currentCell.isEmpty() && sl &&
toolHandle->getTool()->getName() == "T_Selection") {
TSelection* ts = toolHandle->getTool()->getSelection();
RasterSelection* rs = dynamic_cast<RasterSelection*>(ts);
if (rs) {
toolHandle->getTool()->onActivate();
rs->pasteSelection();
return;
}
}
if (!initUndo) {
initUndo = true;
TUndoManager::manager()->beginBlock();
}
rasterImageData = strokesData->toToonzImageData(ti); rasterImageData = strokesData->toToonzImageData(ti);
pasteRasterImageInCell(r0, c0, rasterImageData); pasteRasterImageInCell(r0, c0, rasterImageData);
} else if (TRasterImageP ri = img) { } else if (TRasterImageP ri = img) {
TXshSimpleLevel* sl = xsh->getCell(r0, c0).getSimpleLevel();
if (!sl) sl = xsh->getCell(r0 - 1, c0).getSimpleLevel();
assert(sl);
ToolHandle* toolHandle = TApp::instance()->getCurrentTool();
TXshCell currentCell = xsh->getCell(r0, c0);
if (!currentCell.isEmpty() && sl &&
toolHandle->getTool()->getName() == "T_Selection") {
TSelection* ts = toolHandle->getTool()->getSelection();
RasterSelection* rs = dynamic_cast<RasterSelection*>(ts);
if (rs) {
toolHandle->getTool()->onActivate();
rs->pasteSelection();
return;
}
}
if (!initUndo) {
initUndo = true;
TUndoManager::manager()->beginBlock();
}
double dpix, dpiy; double dpix, dpiy;
ri->getDpi(dpix, dpiy); ri->getDpi(dpix, dpiy);
if (dpix == 0 || dpiy == 0) { if (dpix == 0 || dpiy == 0) {
@ -1890,8 +1932,30 @@ void TCellSelection::pasteCells() {
} }
rasterImageData = strokesData->toFullColorImageData(ri); rasterImageData = strokesData->toFullColorImageData(ri);
pasteRasterImageInCell(r0, c0, rasterImageData); pasteRasterImageInCell(r0, c0, rasterImageData);
} else }
pasteStrokesInCell(r0, c0, strokesData); else {
TXshSimpleLevel* sl = xsh->getCell(r0, c0).getSimpleLevel();
if (!sl) sl = xsh->getCell(r0 - 1, c0).getSimpleLevel();
assert(sl);
ToolHandle* toolHandle = TApp::instance()->getCurrentTool();
TXshCell currentCell = xsh->getCell(r0, c0);
if (!currentCell.isEmpty() && sl &&
toolHandle->getTool()->getName() == "T_Selection") {
TSelection* ts = toolHandle->getTool()->getSelection();
StrokeSelection* ss = dynamic_cast<StrokeSelection*>(ts);
if (ss) {
toolHandle->getTool()->onActivate();
ss->paste();
return;
}
}
if (!initUndo) {
initUndo = true;
TUndoManager::manager()->beginBlock();
}
pasteStrokesInCell(r0, c0, strokesData);
}
} }
// Raster Time // Raster Time
// See if an image was copied from outside Tahoma // See if an image was copied from outside Tahoma
@ -1926,13 +1990,28 @@ void TCellSelection::pasteCells() {
} }
// Convert non-plain raster data to strokes data // Convert non-plain raster data to strokes data
if (vi && clipImage.isNull()) { if (vi && clipImage.isNull()) {
if (!initUndo) {
initUndo = true; TXshSimpleLevel* sl = xsh->getCell(r0, c0).getSimpleLevel();
TUndoManager::manager()->beginBlock(); if (!sl) sl = xsh->getCell(r0 - 1, c0).getSimpleLevel();
}
TXshSimpleLevel *sl = xsh->getCell(r0, c0).getSimpleLevel();
if (!sl) sl = xsh->getCell(r0 - 1, c0).getSimpleLevel();
assert(sl); assert(sl);
ToolHandle* toolHandle = TApp::instance()->getCurrentTool();
TXshCell currentCell = xsh->getCell(r0, c0);
if (!currentCell.isEmpty() && sl &&
toolHandle->getTool()->getName() == "T_Selection") {
TSelection* ts = toolHandle->getTool()->getSelection();
StrokeSelection* ss = dynamic_cast<StrokeSelection*>(ts);
if (ss) {
toolHandle->getTool()->onActivate();
ss->paste();
return;
}
}
if (!initUndo) {
initUndo = true;
TUndoManager::manager()->beginBlock();
}
StrokesData *strokesData = rasterImageData->toStrokesData(sl->getScene()); StrokesData *strokesData = rasterImageData->toStrokesData(sl->getScene());
pasteStrokesInCell(r0, c0, strokesData); pasteStrokesInCell(r0, c0, strokesData);
// end strokes stuff // end strokes stuff
@ -2010,11 +2089,13 @@ void TCellSelection::pasteCells() {
clipImage.width() / 2, clipImage.height() / 2)); clipImage.width() / 2, clipImage.height() / 2));
FullColorImageData *qimageData = new FullColorImageData(); FullColorImageData *qimageData = new FullColorImageData();
TPalette *p; TPalette *p;
if (!ri || newLevel) if (!ri || !ri->getPalette() || newLevel)
p = TApp::instance()->getPaletteController()->getDefaultPalette( p = TApp::instance()
OVL_XSHLEVEL); ->getPaletteController()
->getDefaultPalette(OVL_XSHLEVEL)
->clone();
else else
p = ri->getPalette(); p = ri->getPalette()->clone();
TDimension dim; TDimension dim;
if (ri && !newLevel) { if (ri && !newLevel) {
dim = ri->getRaster()->getSize(); dim = ri->getRaster()->getSize();
@ -2028,6 +2109,19 @@ void TCellSelection::pasteCells() {
// rasterImageData holds all the info either way now. // rasterImageData holds all the info either way now.
} }
ToolHandle *toolHandle = TApp::instance()->getCurrentTool();
TXshCell currentCell = xsh->getCell(r0, c0);
if (!currentCell.isEmpty() && sl &&
toolHandle->getTool()->getName() == "T_Selection") {
TSelection *ts = toolHandle->getTool()->getSelection();
RasterSelection *rs = dynamic_cast<RasterSelection *>(ts);
if (rs) {
toolHandle->getTool()->onActivate();
rs->pasteSelection();
return;
}
}
if (!initUndo) { if (!initUndo) {
initUndo = true; initUndo = true;
TUndoManager::manager()->beginBlock(); TUndoManager::manager()->beginBlock();

View file

@ -1671,7 +1671,13 @@ void Filmstrip::updateCurrentLevelComboItem() {
} }
for (int i = 0; i < m_levels.size(); i++) { for (int i = 0; i < m_levels.size(); i++) {
if (currentLevel->getName() == m_levels[i]->getName()) { TXshSimpleLevel* tempLevel = m_levels[i];
std::wstring currName = currentLevel->getName();
int type = tempLevel->getType();
if (type < 0 || type > MESH_XSHLEVEL) break;
std::wstring tempName = tempLevel->getName();
if (!currentLevel->isEmpty() && !tempLevel->isEmpty() && currentLevel->getName() == tempLevel->getName()) {
m_chooseLevelCombo->setCurrentIndex(i); m_chooseLevelCombo->setCurrentIndex(i);
return; return;
} }

View file

@ -37,6 +37,9 @@
#include "toonz/tcamera.h" #include "toonz/tcamera.h"
#include "toonz/preferences.h" #include "toonz/preferences.h"
#include "trop.h" #include "trop.h"
#include "tools/toolhandle.h"
#include "tools/rasterselection.h"
#include "tools/strokeselection.h"
#include "toonzqt/gutil.h" #include "toonzqt/gutil.h"
@ -274,6 +277,11 @@ bool pasteAreasWithoutUndo(const QMimeData *data, TXshSimpleLevel *sl,
ToolUtils::updateSaveBox(sl, *it); ToolUtils::updateSaveBox(sl, *it);
} }
} else if (ri) { } else if (ri) {
if (!ri->getPalette())
ri->setPalette(TApp::instance()
->getPaletteController()
->getDefaultPalette(sl->getType())
->clone());
TRasterP ras; TRasterP ras;
double dpiX = 0, dpiY = 0; double dpiX = 0, dpiY = 0;
double imgDpiX = 0, imgDpiY = 0; double imgDpiX = 0, imgDpiY = 0;
@ -652,6 +660,11 @@ public:
TRop::over(ti->getRaster(), app, pos, affine); TRop::over(ti->getRaster(), app, pos, affine);
ToolUtils::updateSaveBox(m_level, *it); ToolUtils::updateSaveBox(m_level, *it);
} else if (ri) { } else if (ri) {
if (!ri->getPalette())
ri->setPalette(TApp::instance()
->getPaletteController()
->getDefaultPalette(m_level->getType())
->clone());
TRasterP ras; TRasterP ras;
double dpiX, dpiY; double dpiX, dpiY;
std::vector<TRectD> rects; std::vector<TRectD> rects;
@ -1624,10 +1637,39 @@ void FilmstripCmd::paste(TXshSimpleLevel *sl, std::set<TFrameId> &frames) {
TUndo *undo = 0; TUndo *undo = 0;
TPaletteP plt = sl->getPalette()->clone(); TPaletteP plt = sl->getPalette()->clone();
QImage clipImage = clipboard->image(); QImage clipImage = clipboard->image();
if (sl && sl->getType() == OVL_XSHLEVEL && !clipImage.isNull()) {
FullColorImageData *fullColorData =
dynamic_cast<FullColorImageData *>(data);
if ((!clipImage.isNull() || fullColorData) &&
sl->getType() != OVL_XSHLEVEL) {
DVGui::error(QObject::tr(
"Can't paste full raster data on a non full raster level."));
return;
}
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
ToolHandle *toolHandle = TApp::instance()->getCurrentTool();
if (toolHandle->getTool()->getName() == "T_Selection") {
TSelection *ts = toolHandle->getTool()->getSelection();
RasterSelection *rs = dynamic_cast<RasterSelection *>(ts);
StrokeSelection *ss = dynamic_cast<StrokeSelection *>(ts);
if (rs) {
toolHandle->getTool()->onActivate();
rs->pasteSelection();
return;
}
if (ss) {
toolHandle->getTool()->onActivate();
ss->paste();
return;
}
}
if (sl->getType() == OVL_XSHLEVEL && !clipImage.isNull()) {
// This stuff is only if we have a pasted image from outside Tahoma // This stuff is only if we have a pasted image from outside Tahoma
if (sl && (sl->getResolution().lx < clipImage.width() || if (sl->getResolution().lx < clipImage.width() ||
sl->getResolution().ly < clipImage.height())) { sl->getResolution().ly < clipImage.height()) {
clipImage = clipImage =
clipImage.scaled(sl->getResolution().lx, sl->getResolution().ly, clipImage.scaled(sl->getResolution().lx, sl->getResolution().ly,
Qt::KeepAspectRatio); Qt::KeepAspectRatio);
@ -1656,6 +1698,7 @@ void FilmstripCmd::paste(TXshSimpleLevel *sl, std::set<TFrameId> &frames) {
bool isPaste = pasteAreasWithoutUndo(data, sl, frames, &tileSet, indices); bool isPaste = pasteAreasWithoutUndo(data, sl, frames, &tileSet, indices);
RasterImageData *rasterImageData = dynamic_cast<RasterImageData *>(data); RasterImageData *rasterImageData = dynamic_cast<RasterImageData *>(data);
StrokesData *strokesData = dynamic_cast<StrokesData *>(data); StrokesData *strokesData = dynamic_cast<StrokesData *>(data);
if (rasterImageData && tileSet) if (rasterImageData && tileSet)
undo = new PasteRasterAreasUndo(sl, frames, tileSet, rasterImageData, undo = new PasteRasterAreasUndo(sl, frames, tileSet, rasterImageData,
plt.getPointer(), isFrameToInsert); plt.getPointer(), isFrameToInsert);