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 *palette = new TPalette;
palette->assign(this);
if (this && this->m_styles.size() > 0) palette->assign(this);
return palette;
}

View file

@ -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();

View file

@ -1024,6 +1024,19 @@ void RasterSelection::makeFloating() {
void RasterSelection::pasteFloatingSelection() {
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);
@ -1126,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;
@ -1140,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);
@ -1166,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;
}
//-----------------------------------------------------------------------------
@ -1177,6 +1191,10 @@ void RasterSelection::pasteSelection() {
if (!image) return;
TXshLevel *xl = app->getCurrentLevel()->getLevel();
TXshSimpleLevel *sl = xl ? xl->getSimpleLevel() : 0;
int levelType = sl ? sl->getType() : NO_XSHLEVEL;
if (!isEditable()) {
DVGui::error(
QObject::tr("The selection cannot be pasted. It is not editable."));
@ -1196,8 +1214,27 @@ void RasterSelection::pasteSelection() {
if (isFloating()) pasteFloatingSelection();
selectNone();
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())
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 (TToonzImageP ti = m_currentImage)
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
// Set up variables
@ -1257,7 +1295,7 @@ void RasterSelection::pasteSelection() {
}
if (!riData) return;
pasteSelection(riData);
if (!pasteSelection(riData)) return;
app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
notify();

View file

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

View file

@ -52,6 +52,8 @@
#include "toonz/tstageobjecttree.h"
#include "toonz/stage.h"
#include "vectorizerpopup.h"
#include "tools/rasterselection.h"
#include "tools/strokeselection.h"
// TnzCore includes
#include "timagecache.h"
@ -706,6 +708,9 @@ bool pasteRasterImageInCellWithoutUndo(int row, int col,
sl = cell.getSimpleLevel();
fid = cell.getFrameId();
img = cell.getImage(true);
if (!img->getPalette()) {
img->setPalette(sl->getPalette());
}
TRasterP ras;
TRasterP outRas;
double imgDpiX, imgDpiY;
@ -1871,15 +1876,52 @@ void TCellSelection::pasteCells() {
xl->getPath().getFrame() != TFrameId::NO_FRAME))
img = cell.getImage(false);
}
RasterImageData *rasterImageData = 0;
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 *rasterImageData = 0;
if (TToonzImageP ti = img) {
rasterImageData = strokesData->toToonzImageData(ti);
pasteRasterImageInCell(r0, c0, rasterImageData);
} 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;
ri->getDpi(dpix, dpiy);
if (dpix == 0 || dpiy == 0) {
@ -1890,9 +1932,31 @@ void TCellSelection::pasteCells() {
}
rasterImageData = strokesData->toFullColorImageData(ri);
pasteRasterImageInCell(r0, c0, rasterImageData);
} else
}
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
// See if an image was copied from outside Tahoma
QImage clipImage = clipboard->image();
@ -1926,13 +1990,28 @@ void TCellSelection::pasteCells() {
}
// Convert non-plain raster data to strokes data
if (vi && clipImage.isNull()) {
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();
}
TXshSimpleLevel *sl = xsh->getCell(r0, c0).getSimpleLevel();
if (!sl) sl = xsh->getCell(r0 - 1, c0).getSimpleLevel();
assert(sl);
StrokesData *strokesData = rasterImageData->toStrokesData(sl->getScene());
pasteStrokesInCell(r0, c0, strokesData);
// end strokes stuff
@ -2010,11 +2089,13 @@ void TCellSelection::pasteCells() {
clipImage.width() / 2, clipImage.height() / 2));
FullColorImageData *qimageData = new FullColorImageData();
TPalette *p;
if (!ri || newLevel)
p = TApp::instance()->getPaletteController()->getDefaultPalette(
OVL_XSHLEVEL);
if (!ri || !ri->getPalette() || newLevel)
p = TApp::instance()
->getPaletteController()
->getDefaultPalette(OVL_XSHLEVEL)
->clone();
else
p = ri->getPalette();
p = ri->getPalette()->clone();
TDimension dim;
if (ri && !newLevel) {
dim = ri->getRaster()->getSize();
@ -2028,6 +2109,19 @@ void TCellSelection::pasteCells() {
// 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) {
initUndo = true;
TUndoManager::manager()->beginBlock();

View file

@ -1671,7 +1671,13 @@ void Filmstrip::updateCurrentLevelComboItem() {
}
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);
return;
}

View file

@ -37,6 +37,9 @@
#include "toonz/tcamera.h"
#include "toonz/preferences.h"
#include "trop.h"
#include "tools/toolhandle.h"
#include "tools/rasterselection.h"
#include "tools/strokeselection.h"
#include "toonzqt/gutil.h"
@ -274,6 +277,11 @@ bool pasteAreasWithoutUndo(const QMimeData *data, TXshSimpleLevel *sl,
ToolUtils::updateSaveBox(sl, *it);
}
} else if (ri) {
if (!ri->getPalette())
ri->setPalette(TApp::instance()
->getPaletteController()
->getDefaultPalette(sl->getType())
->clone());
TRasterP ras;
double dpiX = 0, dpiY = 0;
double imgDpiX = 0, imgDpiY = 0;
@ -652,6 +660,11 @@ public:
TRop::over(ti->getRaster(), app, pos, affine);
ToolUtils::updateSaveBox(m_level, *it);
} else if (ri) {
if (!ri->getPalette())
ri->setPalette(TApp::instance()
->getPaletteController()
->getDefaultPalette(m_level->getType())
->clone());
TRasterP ras;
double dpiX, dpiY;
std::vector<TRectD> rects;
@ -1624,10 +1637,39 @@ void FilmstripCmd::paste(TXshSimpleLevel *sl, std::set<TFrameId> &frames) {
TUndo *undo = 0;
TPaletteP plt = sl->getPalette()->clone();
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
if (sl && (sl->getResolution().lx < clipImage.width() ||
sl->getResolution().ly < clipImage.height())) {
if (sl->getResolution().lx < clipImage.width() ||
sl->getResolution().ly < clipImage.height()) {
clipImage =
clipImage.scaled(sl->getResolution().lx, sl->getResolution().ly,
Qt::KeepAspectRatio);
@ -1656,6 +1698,7 @@ void FilmstripCmd::paste(TXshSimpleLevel *sl, std::set<TFrameId> &frames) {
bool isPaste = pasteAreasWithoutUndo(data, sl, frames, &tileSet, indices);
RasterImageData *rasterImageData = dynamic_cast<RasterImageData *>(data);
StrokesData *strokesData = dynamic_cast<StrokesData *>(data);
if (rasterImageData && tileSet)
undo = new PasteRasterAreasUndo(sl, frames, tileSet, rasterImageData,
plt.getPointer(), isFrameToInsert);