示例#1
0
	void undo() const
	{
		int i;
		//TPalette *palette = m_matchlinePalette->clone();
		//m_sl->setPalette(palette);
		for (i = 0; i < m_fids.size(); i++) {
			QString id = "DeleteMatchlineUndo" + QString::number((uintptr_t) this) + "-" + QString::number(i);
			TImageP img = TImageCache::instance()->get(id, false)->cloneImage();

			m_sl->setFrame(m_fids[i], img);
			ToolUtils::updateSaveBox(m_sl, m_fids[i]);
		}
		//TApp::instance()->getPaletteController()->getCurrentLevelPalette()->setPalette(palette);

		if (m_xl)
			invalidateIcons(m_xl, m_fids);
		m_sl->setDirtyFlag(true);
		TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
	}
示例#2
0
	void undo() const
	{
		std::map<TFrameId, QString>::const_iterator it = m_images.begin();
		TPalette *palette = m_palette->clone();
		m_level->setPalette(palette);
		vector<TFrameId> fids;
		for (; it != m_images.end(); ++it) //, ++mit)
		{
			QString id = "MergeCmappedUndo" + QString::number(m_mergeCmappedSessionId) + "-" + QString::number(it->first.getNumber());
			TImageP img = TImageCache::instance()->get(id, false)->cloneImage();
			img->setPalette(palette);
			m_level->setFrame(it->first, img);
			fids.push_back(it->first);
		}

		removeLevel(m_xl);

		TApp::instance()->getPaletteController()->getCurrentLevelPalette()->setPalette(palette);
		m_level->setDirtyFlag(true);
		TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
	}
示例#3
0
	void undo() const
	{
		QApplication::setOverrideCursor(Qt::WaitCursor);

		std::map<TFrameId, QString>::const_iterator it = m_images.begin();

		vector<TFrameId> fids;
		m_level->setPalette(m_palette);
		for (; it != m_images.end(); ++it) //, ++mit)
		{
			QString id = "MergeColumnsUndo" + QString::number(m_matchlineSessionId) + "-" + QString::number(it->first.getNumber());
			TImageP img = TImageCache::instance()->get(id, false)->cloneImage();
			m_level->setFrame(it->first, img);
			fids.push_back(it->first);
		}

		if (m_xl)
			invalidateIcons(m_xl.getPointer(), fids);

		m_level->setDirtyFlag(true);
		TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
		QApplication::restoreOverrideCursor();
	}
示例#4
0
void CameraTestToggleCommand::postProcess() {
  TApp *app                   = TApp::instance();
  CleanupSettingsModel *model = CleanupSettingsModel::instance();

  TXshSimpleLevel *sl;
  TFrameId fid;
  model->getCleanupFrame(sl, fid);

  assert(sl);
  if (!sl) return;

  // Retrieve transformed image
  TRasterImageP transformed;
  {
    TRasterImageP original;
    model->getCameraTestData(original, transformed);
  }

  // Substitute current frame image with previewed one
  sl->setFrame(fid, transformed);

  TApp::instance()->getCurrentLevel()->notifyLevelChange();
}
QScriptValue foo(QScriptContext *ctx, QScriptEngine *eng)
{
	int r = ctx->argument(0).toInteger();
	int c = ctx->argument(1).toInteger();
	QScriptValue levelArg = ctx->argument(2);

	ScriptWrapper::Level *level = dynamic_cast<ScriptWrapper::Level *>(levelArg.toQObject());
	if (level) {
		TXshSimpleLevel *sl = level->getLevel();
		if (!sl)
			return QScriptValue(0);

		TFrameId fid(1);
		if (!sl->isFid(fid))
			sl->setFrame(fid, sl->createEmptyFrame());

		ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
		scene->getXsheet()->setCell(r, c, TXshCell(sl, fid));
		TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
	}

	return QScriptValue(1);
}
示例#6
0
void PreviewToggleCommand::postProcess() {
  TApp *app                   = TApp::instance();
  CleanupSettingsModel *model = CleanupSettingsModel::instance();

  TXshSimpleLevel *sl;
  TFrameId fid;
  model->getCleanupFrame(sl, fid);

  assert(sl);
  if (!sl) return;

  // Retrieve transformed image
  TRasterImageP transformed;
  {
    TRasterImageP original;
    TAffine transform;

    model->getPreviewData(original, transformed, transform);
    if (!transformed) return;
  }

  // Perform post-processing
  TRasterImageP preview(
      TCleanupper::instance()->processColors(transformed->getRaster()));

  TPointD dpi;
  transformed->getDpi(dpi.x, dpi.y);
  preview->setDpi(dpi.x, dpi.y);

  transformed = TRasterImageP();

  // Substitute current frame image with previewed one
  sl->setFrame(fid, preview);

  TApp::instance()->getCurrentLevel()->notifyLevelChange();
}
示例#7
0
bool LevelCreatePopup::apply() {
  TApp *app = TApp::instance();
  int row   = app->getCurrentFrame()->getFrame();
  int col   = app->getCurrentColumn()->getColumnIndex();
  int i, j;

  ToonzScene *scene = app->getCurrentScene()->getScene();
  TXsheet *xsh      = scene->getXsheet();

  bool validColumn = true;
  if (xsh->getColumn(col))
    validColumn =
        xsh->getColumn(col)->getColumnType() == TXshColumn::eLevelType;

  int from   = (int)m_fromFld->getValue();
  int to     = (int)m_toFld->getValue();
  int inc    = (int)m_incFld->getValue();
  int step   = (int)m_stepFld->getValue();
  double w   = m_widthFld->getValue();
  double h   = m_heightFld->getValue();
  double dpi = m_dpiFld->getValue();
  int xres   = std::max(tround(w * dpi), 1);
  int yres   = std::max(tround(h * dpi), 1);
  int lType  = getLevelType();

  std::wstring levelName = m_nameFld->text().toStdWString();
  // tolgo i blanks prima e dopo

  i = levelName.find_first_not_of(L' ');
  if (i == (int)std::wstring::npos)
    levelName = L"";
  else {
    int j = levelName.find_last_not_of(L' ');
    assert(j != (int)std::wstring::npos);
    levelName = levelName.substr(i, j - i + 1);
  }
  if (levelName.empty()) {
    error(tr("No level name specified: please choose a valid level name"));
    return false;
  }

  if (from > to) {
    error(tr("Invalid frame range"));
    return false;
  }
  if (inc <= 0) {
    error(tr("Invalid increment value"));
    return false;
  }
  if (step <= 0) {
    error(tr("Invalid step value"));
    return false;
  }

  int numFrames = step * (((to - from) / inc) + 1);

  if (scene->getLevelSet()->getLevel(levelName)) {
    error(
        tr("The level name specified is already used: please choose a "
           "different level name"));
    m_nameFld->selectAll();
    return false;
  }

  TFilePath parentDir(m_pathFld->getPath().toStdWString());
  TFilePath fp =
      scene->getDefaultLevelPath(lType, levelName).withParentDir(parentDir);

  TFilePath actualFp = scene->decodeFilePath(fp);
  if (TSystem::doesExistFileOrLevel(actualFp)) {
    error(
        tr("The level name specified is already used: please choose a "
           "different level name"));
    m_nameFld->selectAll();
    return false;
  }
  parentDir = scene->decodeFilePath(parentDir);
  if (!TFileStatus(parentDir).doesExist()) {
    QString question;
    /*question = "Folder " +toQString(parentDir) +
                                                     " doesn't exist.\nDo you
       want to create it?";*/
    question = tr("Folder %1 doesn't exist.\nDo you want to create it?")
                   .arg(toQString(parentDir));
    int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"));
    if (ret == 0 || ret == 2) return false;
    try {
      TSystem::mkDir(parentDir);
      DvDirModel::instance()->refreshFolder(parentDir.getParentDir());
    } catch (...) {
      error(tr("Unable to create") + toQString(parentDir));
      return false;
    }
  }

  TXshLevel *level =
      scene->createNewLevel(lType, levelName, TDimension(), 0, fp);
  TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(level);
  assert(sl);
  sl->setPath(fp, true);
  if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) {
    sl->getProperties()->setDpiPolicy(LevelProperties::DP_ImageDpi);
    sl->getProperties()->setDpi(dpi);
    sl->getProperties()->setImageDpi(TPointD(dpi, dpi));
    sl->getProperties()->setImageRes(TDimension(xres, yres));
  }

  /*-- これからLevelを配置しようとしているセルが空いているかどうかのチェック
   * --*/
  bool areColumnsShifted = false;
  TXshCell cell          = xsh->getCell(row, col);
  bool isInRange         = true;
  for (i = row; i < row + numFrames; i++) {
    if (!cell.isEmpty()) {
      isInRange = false;
      break;
    }
    cell = xsh->getCell(i, col);
  }
  if (!validColumn) {
    isInRange = false;
  }

  /*-- 別のLevelに占有されていた場合、Columnを1つ右に移動 --*/
  if (!isInRange) {
    col += 1;
    TApp::instance()->getCurrentColumn()->setColumnIndex(col);
    areColumnsShifted = true;
    xsh->insertColumn(col);
  }

  CreateLevelUndo *undo =
      new CreateLevelUndo(row, col, numFrames, step, areColumnsShifted);
  TUndoManager::manager()->add(undo);

  for (i = from; i <= to; i += inc) {
    TFrameId fid(i);
    TXshCell cell(sl, fid);
    if (lType == PLI_XSHLEVEL)
      sl->setFrame(fid, new TVectorImage());
    else if (lType == TZP_XSHLEVEL) {
      TRasterCM32P raster(xres, yres);
      raster->fill(TPixelCM32());
      TToonzImageP ti(raster, TRect());
      ti->setDpi(dpi, dpi);
      sl->setFrame(fid, ti);
      ti->setSavebox(TRect(0, 0, xres - 1, yres - 1));
    } else if (lType == OVL_XSHLEVEL) {
      TRaster32P raster(xres, yres);
      raster->clear();
      TRasterImageP ri(raster);
      ri->setDpi(dpi, dpi);
      sl->setFrame(fid, ri);
    }
    for (j = 0; j < step; j++) xsh->setCell(row++, col, cell);
  }

  if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) {
    sl->save(fp);
    DvDirModel::instance()->refreshFolder(fp.getParentDir());
  }

  undo->onAdd(sl);

  app->getCurrentScene()->notifySceneChanged();
  app->getCurrentScene()->notifyCastChange();
  app->getCurrentXsheet()->notifyXsheetChanged();

  // Cambia l'immagine corrente ma non cambiano ne' il frame ne' la colonna
  // corrente
  // (entrambi notificano il cambiamento dell'immagine al tool).
  // devo verfificare che sia settato il tool giusto.
  app->getCurrentTool()->onImageChanged(
      (TImage::Type)app->getCurrentImageType());
  return true;
}
示例#8
0
void mergeCmapped(int column, int mColumn, const QString &fullpath, bool isRedo)
{
	static int MergeCmappedSessionId = 0;
	MergeCmappedSessionId++;

	TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
	int start, end;
	int mStart, mEnd;
	xsh->getCellRange(column, start, end);
	xsh->getCellRange(mColumn, mStart, mEnd);

	if (start > end)
		return;
	vector<TXshCell> cell(max(end, mEnd) - min(start, mStart) + 1);
	vector<TXshCell> mCell(cell.size());

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

	if (mColumn != -1)
		xsh->getCells(min(start, mStart), mColumn, cell.size(), &(mCell[0]));

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

	vector<MergeCmappedPair> matchingLevels;

	std::map<MergedPair, TFrameId> computedMergedMap;

	TXshSimpleLevel *level = 0, *mLevel = 0;
	TXshLevel *xl;

	std::map<TFrameId, QString> images;
	double dpix = 0, dpiy = 0;
	for (int i = 0; i < (int)cell.size(); i++) {
		if (!cell[i].isEmpty() && dpix == 0)
			((TToonzImageP)(cell[i].getImage(false)))->getDpi(dpix, dpiy);

		if (!level) {
			level = cell[i].getSimpleLevel();
			xl = cell[i].m_level.getPointer();
		}
		if (!mLevel)
			mLevel = mCell[i].getSimpleLevel();
	}

	if (!level || !mLevel)
		return;

	TFilePath fp(fullpath.toStdString());

	TXshLevel *txl = level->getScene()->createNewLevel(level->getType(), fp.getWideName(), level->getResolution());
	TXshSimpleLevel *newLevel = txl->getSimpleLevel();
	newLevel->setPalette(level->getPalette());
	newLevel->clonePropertiesFrom(level);
	newLevel->setPath(fp);

	TApp::instance()->getCurrentScene()->notifySceneChanged();
	TApp::instance()->getCurrentScene()->notifyCastChange();
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();

	int count = 0;
	for (int i = 0; i < (int)cell.size(); i++) {
		if (cell[i].isEmpty() && mCell[i].isEmpty())
			continue;

		TAffine imgAff, matchAff;

		getColumnPlacement(imgAff, xsh, min(start, mStart) + i, column, false);
		getColumnPlacement(matchAff, xsh, min(start, mStart) + i, mColumn, false);

		//std::map<TFrameId, TFrameId>::iterator it;
		MergedPair mp(cell[i].isEmpty() ? TFrameId() : cell[i].getFrameId(),
					  mCell[i].isEmpty() ? TFrameId() : mCell[i].getFrameId(),
					  imgAff.inv() * matchAff);

		std::map<MergedPair, TFrameId>::iterator computedMergedIt = computedMergedMap.find(mp);

		if (computedMergedIt != computedMergedMap.end()) {
			TXshCell newCell(newLevel, computedMergedIt->second);
			xsh->setCell(i, column, newCell);
			cell[i] = newCell;
			continue;
		}

		TFrameId newFid(++count); //level->getLastFid().getNumber()+1);
		TDimension dim = level->getResolution();
		TToonzImageP newImage;
		if (cell[i].isEmpty()) {
			newImage = TToonzImageP(TRasterCM32P(dim), TRect(0, 0, dim.lx - 1, dim.ly - 1));
			newImage->setDpi(dpix, dpiy);
		} else
			newImage = (TToonzImageP)(cell[i].getImage(false)->cloneImage());

		newImage->setPalette(level->getPalette());

		newLevel->setFrame(newFid, newImage);
		TXshCell newCell(newLevel, newFid);
		xsh->setCell(i, column, newCell);
		computedMergedMap[mp] = newCell.getFrameId();

		cell[i] = newCell;

		TImageP img = cell[i].getImage(true);
		TImageP match = mCell[i].getImage(true);
		TFrameId fid = cell[i].m_frameId;
		TFrameId mFid = mCell[i].m_frameId;

		if (!img || !match)
			continue;

		TToonzImageP timg = (TToonzImageP)img;
		TToonzImageP tmatch = (TToonzImageP)match;

		QString id = "MergeCmappedUndo" + QString::number(MergeCmappedSessionId) + "-" + QString::number(fid.getNumber());
		TImageCache::instance()->add(id, timg->clone());
		images[fid] = id;

		TAffine dpiAff = getDpiAffine(level, fid);
		TAffine mdpiAff = getDpiAffine(mLevel, mFid);
		matchingLevels.push_back(MergeCmappedPair(cell[i], imgAff * dpiAff, mCell[i], matchAff * mdpiAff));
	}

	if (!isRedo) {
		TPalette *plt = level->getPalette();

		TPaletteHandle *pltHandle = new TPaletteHandle();
		pltHandle->setPalette(plt);
		int styleCount = plt->getStyleCount();

		TUndoManager::manager()->add(new MergeCmappedUndo(txl, MergeCmappedSessionId,
														  column,
														  level, images,
														  mColumn,
														  plt));
	}

	removeLevel(xl);
	QApplication::setOverrideCursor(Qt::WaitCursor);
	mergeCmapped(matchingLevels);
	QApplication::restoreOverrideCursor();

	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;

		TXshSimpleLevel *sl = cell[i].getSimpleLevel();
		const TFrameId &fid = cell[i].m_frameId;

		ToolUtils::updateSaveBox(sl, fid);
		IconGenerator::instance()->invalidate(sl, fid);
		sl->setDirtyFlag(true);
	}

	newLevel->setDirtyFlag(true);
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}
示例#9
0
TImage *TTool::touchImage() {
  if (!m_application) return 0;

  m_cellsData.clear();

  m_isLevelCreated  = false;
  m_isFrameCreated  = false;
  Preferences *pref = Preferences::instance();

  bool isAutoCreateEnabled   = pref->isAutoCreateEnabled();
  bool animationSheetEnabled = pref->isAnimationSheetEnabled();
  bool isAutoStretchEnabled  = pref->isAutoStretchEnabled();

  TFrameHandle *currentFrame    = m_application->getCurrentFrame();
  TXshLevelHandle *currentLevel = m_application->getCurrentLevel();

  if (currentFrame->isEditingLevel()) {
    // Editing level

    // no level => return 0
    TXshLevel *xl = currentLevel->getLevel();
    if (!xl) return 0;
    TXshSimpleLevel *sl = xl->getSimpleLevel();
    if (!sl || sl->isEmpty()) return 0;

    TFrameId fid = currentFrame->getFid();
    TImageP img  = sl->getFrame(fid, true);
    if (!img) {
      // no drawing found
      if (sl->isSubsequence() || sl->isReadOnly() || !isAutoCreateEnabled)
        return 0;

      // create a new drawing
      img = sl->createEmptyFrame();
      sl->setFrame(fid, img);
      currentLevel->notifyLevelChange();
      m_isFrameCreated = true;
    }
    return img.getPointer();
  } else {
    // editing xsheet
    if (m_application->getCurrentObject()->isSpline()) return 0;

    TSceneHandle *currentScene = m_application->getCurrentScene();
    ToonzScene *scene          = currentScene->getScene();
    int row                    = currentFrame->getFrame();
    int col = m_application->getCurrentColumn()->getColumnIndex();
    if (col < 0) return 0;

    TXsheetHandle *currentXsheet = m_application->getCurrentXsheet();
    TXsheet *xsh                 = currentXsheet->getXsheet();
    if (!xsh) return 0;

    TXshCell cell       = xsh->getCell(row, col);
    TXshSimpleLevel *sl = cell.getSimpleLevel();

    if (sl != 0) {
      // current cell is not empty
      if (isAutoCreateEnabled && animationSheetEnabled && row > 0 &&
          xsh->getCell(row - 1, col) == xsh->getCell(row, col)) {
        // animationSheet is enabled and the current cell is a "hold". We must
        // create a new drawing.
        // measure the hold length (starting from the current row) : r0-r1
        int r0 = row, r1 = row;
        if (isAutoStretchEnabled)
          while (xsh->getCell(r1 + 1, col) == cell) r1++;
        // find the proper frameid (possibly addisng suffix, in order to avoid a
        // fid already used)
        TFrameId fid = getNewFrameId(sl, row);
        // create the new drawing
        TImageP img      = sl->createEmptyFrame();
        m_isFrameCreated = true;
        // insert the drawing in the level
        sl->setFrame(fid, img);
        // update the cell
        cell = TXshCell(sl, fid);
        // update the xsheet (change the current cell and possibly all the
        // following "hold")
        for (int r = r0; r <= r1; r++) xsh->setCell(r, col, cell);
        // notify
        currentXsheet->notifyXsheetChanged();
        currentScene->notifyCastChange();
        currentLevel->notifyLevelChange();
        m_cellsData.push_back(r0);
        m_cellsData.push_back(r1);
        m_cellsData.push_back(0);
      }
      // we've found the image. return it.
      return cell.getImage(true).getPointer();
    }

    // current cell is empty.
    if (!isAutoCreateEnabled) return 0;

    // get the column range
    int r0, r1;
    xsh->getCellRange(col, r0, r1);

    if (animationSheetEnabled && r0 <= r1) {
      // animation sheet enabled and not empty column. We must create a new
      // drawing in the column level and possibly add "holds"

      // find the last not-empty cell before the current one (a) and the first
      // after (b)
      int a = row - 1, b = row + 1;
      while (a >= r0 && xsh->getCell(a, col).isEmpty()) a--;
      while (b <= r1 && xsh->getCell(b, col).isEmpty()) b++;

      // find the level we must attach to
      if (a >= r0) {
        // there is a not-emtpy cell before the current one
        sl = xsh->getCell(a, col).getSimpleLevel();
      } else if (b <= r1) {
        sl = xsh->getCell(b, col).getSimpleLevel();
      }
      if (sl) {
        // note: sl should be always !=0 (the column is not empty)
        // if - for some reason - it is ==0 then we skip to the standard (i.e.
        // !animationSheetEnabled) beahviour

        // create the drawing
        // find the proper frameid (possibly addisng suffix, in order to avoid a
        // fid already used)
        TFrameId fid = getNewFrameId(sl, row);
        // create the new drawing
        TImageP img      = sl->createEmptyFrame();
        m_isFrameCreated = true;
        // insert the drawing in the level
        sl->setFrame(fid, img);
        // update the cell
        cell = TXshCell(sl, fid);
        xsh->setCell(row, col, cell);

        // create holds
        if (!isAutoStretchEnabled) {
          m_cellsData.push_back(row);
          m_cellsData.push_back(row);
          m_cellsData.push_back(2);  // vuoto => nuovo
        } else {
          if (a >= r0) {
            // create a hold before : [a+1, row-1]
            TXshCell aCell = xsh->getCell(a, col);
            for (int i = a + 1; i < row; i++) xsh->setCell(i, col, aCell);
            m_cellsData.push_back(a + 1);
            m_cellsData.push_back(row - 1);
            m_cellsData.push_back(1);  // vuoto => vecchio

            if (b <= r1 && xsh->getCell(b, col).getSimpleLevel() == sl) {
              // create also a hold after
              for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell);
              m_cellsData.push_back(row);
              m_cellsData.push_back(b - 1);
              m_cellsData.push_back(2);  // vuoto => nuovo
            } else {
              m_cellsData.push_back(row);
              m_cellsData.push_back(row);
              m_cellsData.push_back(2);  // vuoto => nuovo
            }
          } else if (b <= r1) {
            // create a hold after
            for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell);
            m_cellsData.push_back(row);
            m_cellsData.push_back(b - 1);
            m_cellsData.push_back(2);  // vuoto => nuovo
          }
        }
      }
      // notify & return
      currentXsheet->notifyXsheetChanged();
      currentScene->notifyCastChange();
      currentLevel->notifyLevelChange();
      return cell.getImage(true).getPointer();
    }

    if (row > 0 && xsh->getCell(row - 1, col).getSimpleLevel() != 0 &&
        !animationSheetEnabled) {
      sl = xsh->getCell(row - 1, col).getSimpleLevel();
      if (sl->getType() != OVL_XSHLEVEL ||
          sl->getPath().getFrame() != TFrameId::NO_FRAME) {
        // la cella precedente contiene un drawing di un livello. animationSheet
        // e' disabilitato
        // creo un nuovo frame
        currentLevel->setLevel(sl);
        if (sl->isSubsequence() || sl->isReadOnly()) return 0;
        TFrameId fid     = sl->index2fid(sl->getFrameCount());
        TImageP img      = sl->createEmptyFrame();
        m_isFrameCreated = true;
        sl->setFrame(fid, img);
        cell = TXshCell(sl, fid);
        xsh->setCell(row, col, cell);
        currentXsheet->notifyXsheetChanged();
        currentScene->notifyCastChange();
        currentLevel->notifyLevelChange();
        return img.getPointer();
      }
    }

    // animation sheet disabled or empty column. autoCreate is enabled: we must
    // create a new level
    int levelType    = pref->getDefLevelType();
    TXshLevel *xl    = scene->createNewLevel(levelType);
    sl               = xl->getSimpleLevel();
    m_isLevelCreated = true;

    // create the drawing
    TFrameId fid = animationSheetEnabled ? getNewFrameId(sl, row) : TFrameId(1);
    TImageP img  = sl->createEmptyFrame();
    m_isFrameCreated = true;
    sl->setFrame(fid, img);
    cell = TXshCell(sl, fid);
    xsh->setCell(row, col, cell);
    if (animationSheetEnabled) {
      m_cellsData.push_back(row);
      m_cellsData.push_back(row);
      m_cellsData.push_back(2);  // vuoto => nuovo
    }

    currentXsheet->notifyXsheetChanged();
    currentScene->notifyCastChange();
    currentLevel->notifyLevelChange();
    return img.getPointer();
  }
}