More paste improvements (#248)
* Some fixes * more little fixes * Make vector selections work too
This commit is contained in:
parent
967ad6de14
commit
dff5b5fdcb
7 changed files with 213 additions and 29 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue