Пример #1
0
void mergeColumns(int column, int mColumn, bool isRedo)
{
	MergeColumnsSessionId++;
	TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
	int start, end;
	xsh->getCellRange(column, start, end);

	if (start > end)
		return;
	vector<TXshCell> cell(end - start + 1);
	vector<TXshCell> mCell(end - start + 1);

	xsh->getCells(start, column, cell.size(), &(cell[0]));

	xsh->getCells(start, mColumn, cell.size(), &(mCell[0]));

	TXshColumn *col = xsh->getColumn(column);
	TXshColumn *mcol = xsh->getColumn(mColumn);

	vector<MatchlinePair> matchingLevels;

	std::set<TFrameId> alreadyDoneSet;

	TXshSimpleLevel *level = 0, *mLevel = 0;
	TXshLevelP xl;
	bool areRasters = false;

	std::map<TFrameId, QString> images;

	for (int i = 0; i < (int)cell.size(); i++) {
		if (cell[i].isEmpty() || mCell[i].isEmpty())
			continue;
		if (!level) {
			level = cell[i].getSimpleLevel();
			xl = cell[i].m_level;
		}

		else if (level != cell[i].getSimpleLevel()) {
			MsgBox(WARNING, QObject::tr("It is not possible to perform a merging involving more than one level per column."));
			return;
		}

		if (!mLevel)
			mLevel = mCell[i].getSimpleLevel();
		else if (mLevel != mCell[i].getSimpleLevel()) {
			MsgBox(WARNING, QObject::tr("It is not possible to perform a merging involving more than one level per column."));
			return;
		}
		TImageP img = cell[i].getImage(true);
		TImageP match = mCell[i].getImage(false);
		TFrameId fid = cell[i].m_frameId;
		TFrameId mFid = mCell[i].m_frameId;

		if (!img || !match)
			continue;

		if (alreadyDoneSet.find(fid) == alreadyDoneSet.end()) {
			TRasterImageP timg = (TRasterImageP)img;
			TRasterImageP tmatch = (TRasterImageP)match;
			TVectorImageP vimg = (TVectorImageP)img;
			TVectorImageP vmatch = (TVectorImageP)match;

			if (timg) {
				if (!tmatch) {
					MsgBox(WARNING, QObject::tr("Only raster levels can be merged to a raster level."));
					return;
				}
				areRasters = true;
			} else if (vimg) {
				if (!vmatch) {
					MsgBox(WARNING, QObject::tr("Only vector levels can be merged to a vector level."));
					return;
				}
			} else {
				MsgBox(WARNING, QObject::tr("It is possible to merge only Toonz vector levels or standard raster levels."));
				return;
			}

			QString id = "MergeColumnsUndo" + QString::number(MergeColumnsSessionId) + "-" + QString::number(fid.getNumber());
			TImageCache::instance()->add(id, (timg) ? timg->cloneImage() : vimg->cloneImage());
			images[fid] = id;
			TAffine imgAff, matchAff;
			getColumnPlacement(imgAff, xsh, start + i, column, false);
			getColumnPlacement(matchAff, xsh, start + i, mColumn, false);
			TAffine dpiAff = getDpiAffine(level, fid);
			TAffine mdpiAff = getDpiAffine(mLevel, mFid);
			matchingLevels.push_back(MatchlinePair(cell[i], imgAff * dpiAff, mCell[i], matchAff * mdpiAff));
			alreadyDoneSet.insert(fid);
		}
	}

	if (matchingLevels.empty()) {
		MsgBox(WARNING, QObject::tr("It is possible to merge only Toonz vector levels or standard raster levels."));
		return;
	}

	ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
	TXshSimpleLevel *simpleLevel = sc->getLevelSet()->getLevel(column)->getSimpleLevel();

	if (!isRedo)
		TUndoManager::manager()->add(new MergeColumnsUndo(xl, MergeColumnsSessionId,
														  column, level, images,
														  mColumn, level->getPalette()));

	if (areRasters) {
		mergeRasterColumns(matchingLevels);
		for (int i = 0; i < (int)cell.size(); i++) //the saveboxes must be updated
		{
			if (cell[i].isEmpty() || mCell[i].isEmpty())
				continue;

			if (!cell[i].getImage(false) || !mCell[i].getImage(false))
				continue;

			ToolUtils::updateSaveBox(cell[i].getSimpleLevel(), cell[i].m_frameId);
		}
	} else
		mergeVectorColumns(matchingLevels);

	TXshLevel *sl = TApp::instance()->getCurrentScene()->getScene()->getLevelSet()->getLevel(column);
	vector<TFrameId> fidsss;
	sl->getFids(fidsss);
	invalidateIcons(sl, fidsss);
	sl->setDirtyFlag(true);
	level->setDirtyFlag(true);
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}