void Vectorizer::setLevel(const TXshSimpleLevelP &level) { m_level = level; //Creo il livello pli TXshSimpleLevel *sl = m_level.getPointer(); if (!sl) return; int rowCount = sl->getFrameCount(); if (rowCount <= 0 || sl->isEmpty()) return; TXshLevel *xl; ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); // Build the new level name wstring levelName = sl->getName() + L"v"; { std::auto_ptr<NameBuilder> nameBuilder(NameBuilder::getBuilder(levelName)); for (;;) { levelName = nameBuilder->getNext(); if (scene->getLevelSet()->getLevel(levelName) == 0) break; } } TFilePath dstPath = sl->getPath().withName(levelName).withType("pli"); dstPath = scene->decodeFilePath(dstPath); bool overWrite = false; if (TSystem::doesExistFileOrLevel(dstPath)) { m_dialogShown = true; std::wstring name = m_dialog->execute(scene, dstPath, true); if (m_dialog->cancelPressed()) return; switch (m_dialog->getChoice()) { case OverwriteDialog::KEEP_OLD: { xl = scene->getLevelSet()->getLevel(levelName); if (!xl) xl = scene->loadLevel(dstPath); m_vLevel = xl->getSimpleLevel(); return; } CASE OverwriteDialog::OVERWRITE : overWrite = true; DEFAULT: levelName = name; } } xl = scene->createNewLevel(PLI_XSHLEVEL, levelName); TXshSimpleLevel *vl = xl->getSimpleLevel(); assert(vl); if (overWrite) { vl->setPath(scene->codeFilePath(dstPath)); vl->setName(levelName); } TPalette *palette = 0; if (sl->getType() == TZP_XSHLEVEL) palette = sl->getPalette(); palette = palette ? palette->clone() : new TPalette; palette->setPaletteName(vl->getName()); vl->setPalette(palette); m_vLevel = vl; }
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; }
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(); }