#include "convertpopup.h"
// Tnz6 includes
#include "menubarcommandids.h"
#include "tapp.h"
#include "formatsettingspopups.h"
#include "filebrowser.h"
// TnzQt includes
#include "toonzqt/gutil.h"
#include "toonzqt/imageutils.h"
#include "toonzqt/menubarcommand.h"
#include "toonzqt/filefield.h"
#include "toonzqt/intfield.h"
#include "toonzqt/colorfield.h"
#include "toonzqt/checkbox.h"
#include "toonzqt/icongenerator.h"
// TnzLib includes
#include "toonz/tscenehandle.h"
#include "toonz/toonzscene.h"
#include "toonz/sceneproperties.h"
#include "toonz/tproject.h"
#include "toutputproperties.h"
#include "convert2tlv.h"
#include "toonz/preferences.h"
// TnzCore includes
#include "tsystem.h"
#include "tfiletype.h"
#include "tlevel_io.h"
#include "tiio.h"
#include "tenv.h"
// Qt includes
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QApplication>
#include <QMainWindow>
#include <QCheckBox>
/*-- Format --*/
TEnv::StringVar ConvertPopupFileFormat("ConvertPopupFileFormat", "tga");
/*-- 背景色 --*/
TEnv::IntVar ConvertPopupBgColorR("ConvertPopupBgColorR", 255);
TEnv::IntVar ConvertPopupBgColorG("ConvertPopupBgColorG", 255);
TEnv::IntVar ConvertPopupBgColorB("ConvertPopupBgColorB", 255);
TEnv::IntVar ConvertPopupBgColorA("ConvertPopupBgColorA", 255);
TEnv::IntVar ConvertPopupSkipExisting("ConvertPopupSkipExisting", 0);
/*-- フレーム番号の前のドットを取る --*/
TEnv::IntVar ConvertPopupRemoveDot("ConvertPopupRemoveDot", 1);
TEnv::IntVar ConvertPopupSaveToNopaint("ConvertPopupSaveToNopaint", 1);
//=============================================================================
// convertPopup
//-----------------------------------------------------------------------------
QMap<string, TPropertyGroup *> ConvertPopup::m_formatProperties;
/*
TRANSLATOR namespace::ConvertPopup
*/
//const QString CreateNewPalette(QObject::tr("Create new palette"));
const QString TlvExtension("tlv");
/*
const QString TlvMode_Unpainted(QObject::tr("Unpainted tlv"));
const QString TlvMode_PaintedFromTwoImages(QObject::tr("Painted tlv from two images"));
const QString TlvMode_PaintedFromNonAA(QObject::tr("Painted tlv from non AA source"));
const QString SameAsPainted(QObject::tr("Same as Painted"));
*/
//=============================================================================
//
// Converter
//
//-----------------------------------------------------------------------------
class ConvertPopup::Converter : public QThread
{
int m_skippedCount;
ConvertPopup *m_parent;
bool m_saveToNopaintOnlyFlag;
public:
Converter(ConvertPopup *parent) : m_parent(parent), m_skippedCount(0) {}
void run();
void convertLevel(const TFilePath &fp);
void convertLevelWithConvert2Tlv(const TFilePath &fp);
int getSkippedCount() const { return m_skippedCount; }
};
void ConvertPopup::Converter::run()
{
ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
DVGui::ProgressDialog *progressDialog = m_parent->m_progressDialog;
int levelCount = m_parent->m_srcFilePaths.size();
TFilePath dstFolder(m_parent->m_saveInFileFld->getPath());
for (int i = 0; !m_parent->m_notifier->abortTask() && i < levelCount; i++) {
TFilePath sourceLevelPath = sc->decodeFilePath(m_parent->m_srcFilePaths[i]);
QString levelName = QString::fromStdString(sourceLevelPath.getLevelName());
// check already exsistent levels
TFilePath dstFilePath = m_parent->getDestinationFilePath(m_parent->m_srcFilePaths[i]);
// perche' ?? TFilePath path=dstFilePath.getParentDir()+(dstFilePath.getName()+"."+dstFilePath.getDottedType());
// if(TSystem::doesExistFileOrLevel(dstFilePath)||TSystem::doesExistFileOrLevel(path))
m_saveToNopaintOnlyFlag = false;
if (TSystem::doesExistFileOrLevel(dstFilePath)) {
if (m_parent->m_skip->isChecked()) {
DVGui::MsgBox(INFORMATION, tr("Level %1 already exists; skipped.").arg(levelName));
m_skippedCount++;
continue;
} else {
/*--- ここで、tlv形式に変換、かつ、UnpaintedTlvが選択され、かつ、
nopaintにバックアップを保存するオプションがONのとき、
出力先をnopaintに変更する。既にあるnopaint内のtlvを消す
---*/
if (m_parent->isSaveTlvBackupToNopaintActive()) {
TFilePath unpaintedLevelPath = dstFilePath.getParentDir() + "nopaint\\" + TFilePath(dstFilePath.getName() + "_np." + dstFilePath.getType());
if (TSystem::doesExistFileOrLevel(unpaintedLevelPath)) {
TSystem::removeFileOrLevel(unpaintedLevelPath);
TSystem::deleteFile((unpaintedLevelPath.getParentDir() + unpaintedLevelPath.getName()).withType("tpl"));
}
m_saveToNopaintOnlyFlag = true;
} else
// todo: handle errors!!
TSystem::removeFileOrLevel(dstFilePath);
}
}
if (m_parent->m_srcFilePaths.size() == 1) {
progressDialog->setLabelText(QString(tr("Converting %1").arg(levelName)));
} else {
progressDialog->setLabelText(QString(tr("Converting level %1 of %2: %3").arg(i + 1).arg(levelCount).arg(levelName)));
}
m_parent->m_notifier->notifyFrameCompleted(0);
convertLevel(sourceLevelPath);
}
}
void ConvertPopup::Converter::convertLevel(const TFilePath &sourceFileFullPath)
{
ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
ConvertPopup *popup = m_parent;
QString levelName = QString::fromStdString(sourceFileFullPath.getLevelName());
std::string ext = popup->m_fileFormat->currentText().toStdString();
TPropertyGroup *prop = popup->getFormatProperties(ext);
TFilePath dstFileFullPath = popup->getDestinationFilePath(sourceFileFullPath);
// bool isTlvNonAA = isTlv && popup->getTlvMode() == TlvMode_PaintedFromNonAA;
bool isTlvNonAA = !(m_parent->getTlvMode().compare(m_parent->TlvMode_PaintedFromNonAA));
TFrameId from, to;
if (TFileType::isLevelFilePath(sourceFileFullPath)) {
popup->getFrameRange(sourceFileFullPath, from, to);
if (from == TFrameId() || to == TFrameId()) {
DVGui::MsgBox(WARNING, tr("Level %1 has no frame; skipped.").arg(levelName));
popup->m_notifier->notifyError();
return;
}
}
TOutputProperties *oprop = TApp::instance()->getCurrentScene()->getScene()->getProperties()->getOutputProperties();
double framerate = oprop->getFrameRate();
if (popup->m_fileFormat->currentText() == TlvExtension) {
// convert to TLV
if (!(m_parent->getTlvMode().compare(m_parent->TlvMode_PaintedFromNonAA))) {
// no AA source (retas)
TPaletteP palette = popup->readUserProvidedPalette();
ImageUtils::convertNaa2Tlv(sourceFileFullPath, dstFileFullPath, from, to, m_parent->m_notifier, palette.getPointer());
} else {
convertLevelWithConvert2Tlv(sourceFileFullPath);
}
} else {
// convert to full-color
TPixel32 bgColor = m_parent->m_bgColorField->getColor();
ImageUtils::convert(sourceFileFullPath, dstFileFullPath, from, to, framerate, prop, m_parent->m_notifier, bgColor,
m_parent->m_removeDotBeforeFrameNumber->isChecked());
}
popup->m_notifier->notifyLevelCompleted(dstFileFullPath);
}
// to use legacy code
void ConvertPopup::Converter::convertLevelWithConvert2Tlv(const TFilePath &sourceFileFullPath)
{
ConvertPopup *popup = m_parent;
Convert2Tlv *tlvConverter = popup->makeTlvConverter(sourceFileFullPath);
TFilePath levelOut = tlvConverter->m_levelOut;
if (m_saveToNopaintOnlyFlag) {
TFilePath unpaintedLevelPath = tlvConverter->m_levelOut.getParentDir() + "nopaint\\" + TFilePath(tlvConverter->m_levelOut.getName() + "_np." + tlvConverter->m_levelOut.getType());
tlvConverter->m_levelOut = unpaintedLevelPath;
}
string errorMessage;
if (!tlvConverter->init(errorMessage)) {
DVGui::MsgBox(WARNING, QString::fromStdString(errorMessage));
tlvConverter->abort();
} else {
int count = tlvConverter->getFramesToConvertCount();
bool stop = false;
for (int j = 0; j < count && !stop; j++) {
if (!tlvConverter->convertNext(errorMessage)) {
stop = true;
DVGui::MsgBox(WARNING, QString::fromStdString(errorMessage));
}
if (popup->m_progressDialog->wasCanceled())
stop = true;
}
if (stop)
tlvConverter->abort();
delete tlvConverter;
}
/*--- nopaintファイルを複製する ---*/
if (m_parent->isSaveTlvBackupToNopaintActive() && !m_saveToNopaintOnlyFlag) {
/*--- nopaintフォルダの作成 ---*/
TFilePath nopaintDir = levelOut.getParentDir() + "nopaint";
if (!TFileStatus(nopaintDir).doesExist()) {
try {
TSystem::mkDir(nopaintDir);
} catch (...) {
return;
}
}
TFilePath unpaintedLevelPath = levelOut.getParentDir() + "nopaint\\" + TFilePath(levelOut.getName() + "_np." + levelOut.getType());
/*--- もしnopaintのファイルがあった場合は消去する ---*/
if (TSystem::doesExistFileOrLevel(unpaintedLevelPath)) {
TSystem::removeFileOrLevel(unpaintedLevelPath);
TSystem::deleteFile((unpaintedLevelPath.getParentDir() + unpaintedLevelPath.getName()).withType("tpl"));
}
TSystem::copyFile(unpaintedLevelPath, levelOut);
/*--- Paletteのコピー ---*/
TFilePath levelPalettePath = levelOut.getParentDir() + TFilePath(levelOut.getName() + ".tpl");
TFilePath unpaintedLevelPalettePath = levelPalettePath.getParentDir() + "nopaint\\" + TFilePath(levelPalettePath.getName() + "_np." + levelPalettePath.getType());
TSystem::copyFile(unpaintedLevelPalettePath, levelPalettePath);
}
/*
QApplication::restoreOverrideCursor();
FileBrowser::refreshFolder(m_srcFilePaths[0].getParentDir());
TFilePath::setUnderscoreFormatAllowed(false);
TFilePath levelOut(converters[i]->m_levelOut);
delete converters[i];
IconGenerator::instance()->invalidate(levelOut);
*/
}
//=============================================================================
ConvertPopup::ConvertPopup(bool specifyInput)
: Dialog(TApp::instance()->getMainWindow(), true, false, "Convert"), m_converter(0), m_isConverting(false)
{
// Su MAC i dialog modali non hanno bottoni di chiusura nella titleBar
setModal(false);
TlvMode_Unpainted = tr("Unpainted tlv");
TlvMode_UnpaintedFromNonAA = tr("Unpainted tlv from non AA source");
TlvMode_PaintedFromTwoImages = tr("Painted tlv from two images");
TlvMode_PaintedFromNonAA = tr("Painted tlv from non AA source");
SameAsPainted = tr("Same as Painted");
CreateNewPalette = tr("Create new palette");
m_fromFld = new IntLineEdit(this);
m_toFld = new IntLineEdit(this);
m_saveInFileFld = new FileField(0, QString(""));
m_fileNameFld = new LineEdit(QString(""));
m_fileFormat = new QComboBox();
m_formatOptions = new QPushButton(tr("Options"), this);
m_bgColorField = new DVGui::ColorField(this, true, TPixel32::Transparent, 35, false);
m_okBtn = new QPushButton(tr("Convert"), this);
m_cancelBtn = new QPushButton(tr("Cancel"), this);
m_bgColorLabel = new QLabel(tr("Bg Color:"));
m_tlvFrame = createTlvSettings();
m_notifier = new ImageUtils::FrameTaskNotifier();
m_progressDialog = new DVGui::ProgressDialog("", tr("Cancel"), 0, 0);
m_skip = new CheckBox(tr("Skip Existing Files"), this);
m_removeDotBeforeFrameNumber = new QCheckBox(tr("Remove dot before frame number"), this);
if (specifyInput)
m_convertFileFld = new FileField(0, QString(""), true);
else
m_convertFileFld = 0;
//-----------------------
//File Format
QStringList formats;
TImageWriter::getSupportedFormats(formats, true);
TLevelWriter::getSupportedFormats(formats, true);
Tiio::Writer::getSupportedFormats(formats, true);
m_fileFormat->addItems(formats);
m_fileFormat->setMaxVisibleItems(15);
m_skip->setChecked(true);
m_okBtn->setDefault(true);
if (specifyInput) {
m_convertFileFld->setFileMode(QFileDialog::ExistingFile);
QStringList filter;
filter << "tif"
<< "tiff"
<< "png"
<< "tga"
<< "tlv"
<< "gif"
<< "bmp"
<< "avi"
<< "mov"
<< "jpg"
<< "pic"
<< "pict"
<< "rgb"
<< "sgi"
<< "png";
m_convertFileFld->setFilters(filter);
m_okBtn->setEnabled(false);
}
m_removeDotBeforeFrameNumber->setChecked(false);
m_progressDialog->setWindowTitle(tr("Convert... "));
m_progressDialog->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint); //Don't show ? and X buttons
m_progressDialog->setWindowModality(Qt::WindowModal);
//----layout
m_topLayout->setMargin(5);
m_topLayout->setSpacing(5);
{
QGridLayout *upperLay = new QGridLayout();
upperLay->setMargin(0);
upperLay->setSpacing(5);
{
upperLay->addWidget(new QLabel(tr("Start:"), this), 0, 0);
upperLay->addWidget(m_fromFld, 0, 1);
upperLay->addWidget(new QLabel(tr(" End:"), this), 0, 2);
upperLay->addWidget(m_toFld, 0, 3);
upperLay->addWidget(new QLabel(tr("Save in:"), this), 1, 0);
upperLay->addWidget(m_saveInFileFld, 1, 1, 1, 4);
upperLay->addWidget(new QLabel(tr("File Name:"), this), 2, 0);
upperLay->addWidget(m_fileNameFld, 2, 1, 1, 4);
upperLay->addWidget(new QLabel(tr("File Format:"), this), 3, 0);
upperLay->addWidget(m_fileFormat, 3, 1, 1, 2);
upperLay->addWidget(m_formatOptions, 3, 3);
upperLay->addWidget(m_bgColorLabel, 4, 0);
upperLay->addWidget(m_bgColorField, 4, 1, 1, 4);
upperLay->addWidget(m_skip, 5, 1, 1, 4);
upperLay->addWidget(m_removeDotBeforeFrameNumber, 6, 1, 1, 4);
}
upperLay->setColumnStretch(0, 0);
upperLay->setColumnStretch(1, 1);
upperLay->setColumnStretch(2, 0);
upperLay->setColumnStretch(3, 1);
upperLay->setColumnStretch(4, 1);
m_topLayout->addLayout(upperLay);
m_topLayout->addWidget(m_tlvFrame);
}
m_buttonLayout->setMargin(0);
m_buttonLayout->setSpacing(20);
{
m_buttonLayout->addWidget(m_okBtn);
m_buttonLayout->addWidget(m_cancelBtn);
}
int formatIndex = m_fileFormat->findText(QString::fromStdString(ConvertPopupFileFormat.getValue()));
if (formatIndex)
m_fileFormat->setCurrentIndex(formatIndex);
else
m_fileFormat->setCurrentIndex(m_fileFormat->findText("tif"));
m_bgColorField->setColor(TPixel32(ConvertPopupBgColorR,
ConvertPopupBgColorG,
ConvertPopupBgColorB,
ConvertPopupBgColorA));
m_skip->setChecked(ConvertPopupSkipExisting ? 1 : 0);
m_removeDotBeforeFrameNumber->setChecked(ConvertPopupRemoveDot ? 1 : 0);
m_saveBackupToNopaint->setChecked(ConvertPopupSaveToNopaint ? 1 : 0);
//--- signal-slot connections
qRegisterMetaType<TFilePath>("TFilePath");
bool ret = true;
ret = ret && connect(m_tlvMode, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(onTlvModeSelected(const QString &)));
ret = ret && connect(m_fromFld, SIGNAL(editingFinished()), this, SLOT(onRangeChanged()));
ret = ret && connect(m_toFld, SIGNAL(editingFinished()), this, SLOT(onRangeChanged()));
ret = ret && connect(m_fileFormat, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(onFormatSelected(const QString &)));
ret = ret && connect(m_formatOptions, SIGNAL(clicked()), this, SLOT(onOptionsClicked()));
ret = ret && connect(m_okBtn, SIGNAL(clicked()), this, SLOT(apply()));
ret = ret && connect(m_cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
ret = ret && connect(m_notifier, SIGNAL(frameCompleted(int)), m_progressDialog, SLOT(setValue(int)));
ret = ret && connect(m_notifier, SIGNAL(levelCompleted(const TFilePath &)), this, SLOT(onLevelConverted(const TFilePath &)));
ret = ret && connect(m_progressDialog, SIGNAL(canceled()), m_notifier, SLOT(onCancelTask()));
if (specifyInput)
ret = ret && connect(m_convertFileFld, SIGNAL(pathChanged()), this, SLOT(onFileInChanged()));
assert(ret);
}
//------------------------------------------------------------------
ConvertPopup::~ConvertPopup()
{
delete m_notifier;
delete m_progressDialog;
delete m_converter;
}
//-----------------------------------------------------------------------------
QString ConvertPopup::getDestinationType() const
{
return m_fileFormat->currentText();
}
//-----------------------------------------------------------------------------
QString ConvertPopup::getTlvMode() const
{
return m_tlvMode->currentText();
}
//-----------------------------------------------------------------------------
QFrame *ConvertPopup::createSvgSettings()
{
bool ret = true;
QHBoxLayout *hLayout;
QFrame *frame = new QFrame();
QVBoxLayout *vLayout = new QVBoxLayout();
frame->setLayout(vLayout);
hLayout = new QHBoxLayout();
hLayout->addWidget(new QLabel(tr("Stroke Mode:")));
hLayout->addWidget(m_tlvMode = new QComboBox());
QStringList items;
items << tr("Centerline") << tr("Outline");
m_tlvMode->addItems(items);
hLayout->addStretch();
vLayout->addLayout(hLayout);
frame->setVisible(false);
return frame;
}
QFrame *ConvertPopup::createTlvSettings()
{
QFrame *frame = new QFrame();
frame->setObjectName("SolidLineFrame");
m_tlvMode = new QComboBox();
m_unpaintedFolderLabel = new QLabel(tr("Unpainted File Folder:"));
m_unpaintedFolder = new FileField(0, QString(tr("Same as Painted")), true);
m_suffixLabel = new QLabel(tr(" Unpainted File Suffix:"));
m_unpaintedSuffix = new LineEdit("_np");
m_applyAutoclose = new QCheckBox(tr("Apply Autoclose"));
m_saveBackupToNopaint = new QCheckBox(tr("Save Backup to \"nopaint\" Folder"));
m_antialias = new QComboBox();
m_antialiasIntensity = new IntLineEdit(0, 50, 0, 100);
m_palettePath = new FileField(0, QString(CreateNewPalette), true);
m_tolerance = new IntLineEdit(0, 0, 0, 255);
m_unpaintedFolder->setFileMode(QFileDialog::DirectoryOnly);
m_unpaintedSuffix->setMaximumWidth(40);
QStringList items1;
items1 << tr("Keep Original Antialiasing") << tr("Add Antialiasing with Intensity:") << tr("Remove Antialiasing using Threshold:");
m_antialias->addItems(items1);
QStringList items;
items << TlvMode_Unpainted << TlvMode_UnpaintedFromNonAA << TlvMode_PaintedFromTwoImages << TlvMode_PaintedFromNonAA;
m_tlvMode->addItems(items);
m_antialiasIntensity->setEnabled(false);
m_palettePath->setMinimumWidth(300);
m_palettePath->setFileMode(QFileDialog::ExistingFile);
m_palettePath->setFilters(QStringList("tpl"));
//m_tolerance->setMaximumWidth(10);
QGridLayout *gridLay = new QGridLayout();
{
gridLay->addWidget(new QLabel(tr("Mode:")), 0, 0, Qt::AlignRight | Qt::AlignVCenter);
gridLay->addWidget(m_tlvMode, 0, 1);
gridLay->addWidget(m_unpaintedFolderLabel, 1, 0, Qt::AlignRight | Qt::AlignVCenter);
gridLay->addWidget(m_unpaintedFolder, 1, 1);
gridLay->addWidget(m_suffixLabel, 1, 2, Qt::AlignRight | Qt::AlignVCenter);
gridLay->addWidget(m_unpaintedSuffix, 1, 3);
gridLay->addWidget(m_applyAutoclose, 2, 1, 1, 3);
gridLay->addWidget(new QLabel(tr("Antialias:")), 3, 0, Qt::AlignRight | Qt::AlignVCenter);
gridLay->addWidget(m_antialias, 3, 1);
gridLay->addWidget(m_antialiasIntensity, 3, 2);
gridLay->addWidget(new QLabel(tr("Palette:")), 4, 0, Qt::AlignRight | Qt::AlignVCenter);
gridLay->addWidget(m_palettePath, 4, 1);
gridLay->addWidget(new QLabel(tr("Tolerance:")), 4, 2, Qt::AlignRight | Qt::AlignVCenter);
gridLay->addWidget(m_tolerance, 4, 3);
gridLay->addWidget(m_saveBackupToNopaint, 5, 1, 1, 3);
}
gridLay->setColumnStretch(0, 0);
gridLay->setColumnStretch(1, 1);
gridLay->setColumnStretch(2, 0);
gridLay->setColumnStretch(3, 0);
frame->setLayout(gridLay);
bool ret = true;
ret = ret && connect(m_antialias, SIGNAL(currentIndexChanged(int)), this, SLOT(onAntialiasSelected(int)));
assert(ret);
frame->setVisible(false);
return frame;
}
//--------------------------------------------------------------------------
void ConvertPopup::onRangeChanged()
{
if (m_srcFilePaths.empty())
return;
TLevelReaderP lr = TLevelReaderP(m_srcFilePaths[0]);
if (lr) {
TLevelP l = lr->loadInfo();
TLevel::Table *t = l->getTable();
if (t->empty())
return;
TFrameId start = t->begin()->first;
TFrameId end = t->rbegin()->first;
if (m_toFld->getValue() > end.getNumber())
m_toFld->setValue(end.getNumber() != -2 ? end.getNumber() : 1);
if (m_fromFld->getValue() < start.getNumber())
m_fromFld->setValue(start.getNumber());
}
}
//-------------------------------------------------------------------
void ConvertPopup::onAntialiasSelected(int index)
{
m_antialiasIntensity->setEnabled(index != 0);
}
//-----------------------------------------------------------------
void ConvertPopup::onFileInChanged()
{
assert(m_convertFileFld);
vector<TFilePath> fps;
TProject *project = TProjectManager::instance()->getCurrentProject().getPointer();
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
fps.push_back(scene->decodeFilePath(TFilePath(m_convertFileFld->getPath().toStdString())));
setFiles(fps);
}
//-------------------------------------------------
void ConvertPopup::onTlvModeSelected(const QString &tlvMode)
{
bool usesTwoImages = TlvMode_PaintedFromTwoImages == tlvMode;
m_unpaintedFolderLabel->setEnabled(usesTwoImages);
m_unpaintedFolder->setEnabled(usesTwoImages);
m_suffixLabel->setEnabled(usesTwoImages);
m_unpaintedSuffix->setEnabled(usesTwoImages);
m_antialias->setEnabled(TlvMode_PaintedFromNonAA != tlvMode);
m_palettePath->setEnabled(TlvMode_PaintedFromNonAA != tlvMode);
m_tolerance->setEnabled(TlvMode_PaintedFromNonAA != tlvMode);
m_saveBackupToNopaint->setEnabled(TlvMode_Unpainted == tlvMode);
}
//-------------------------------------------------
void ConvertPopup::onFormatSelected(const QString &format)
{
onFormatChanged(format);
bool isTlv = format == TlvExtension;
bool isPli = format == "svg";
m_formatOptions->setVisible(!isTlv);
m_bgColorField->setVisible(!isTlv && !isPli);
m_bgColorLabel->setVisible(!isTlv && !isPli);
m_tlvFrame->setVisible(isTlv);
//m_svgFrame->setVisible(isPli);
if (isTlv) {
bool isPainted = m_tlvMode->currentText() == TlvMode_PaintedFromTwoImages;
m_unpaintedFolderLabel->setEnabled(isPainted);
m_unpaintedFolder->setEnabled(isPainted);
m_suffixLabel->setEnabled(isPainted);
m_unpaintedSuffix->setEnabled(isPainted);
m_saveBackupToNopaint->setEnabled(m_tlvMode->currentText() == TlvMode_Unpainted);
}
}
//------------------------------------------------------------------
void ConvertPopup::setFiles(const vector<TFilePath> &fps)
{
m_okBtn->setEnabled(true);
m_fileFormat->setEnabled(true);
m_fileFormat->removeItem(m_fileFormat->findText("svg"));
bool areFullcolor = true;
bool areVector = false;
for (int i = 0; i < (int)fps.size(); i++) {
TFileType::Type type = TFileType::getInfo(fps[i]);
if (!TFileType::isFullColor(type)) {
areFullcolor = false;
if (TFileType::isVector(type))
areVector = true;
break;
}
}
#ifndef BRAVO
int currIndex = m_fileFormat->currentIndex();
int tlvIndex = m_fileFormat->findText(TlvExtension);
if (areFullcolor) {
if (tlvIndex < 0)
m_fileFormat->addItem(TlvExtension);
} else if (areVector) {
int svgIndex = m_fileFormat->findText("svg");
if (svgIndex < 0)
m_fileFormat->addItem("svg");
m_fileFormat->setCurrentIndex(m_fileFormat->findText("svg"));
m_fileFormat->setEnabled(false);
onFormatSelected("svg");
} else
{
if (tlvIndex >= 0) {
int index = m_fileFormat->currentIndex();
m_fileFormat->removeItem(tlvIndex);
}
}
#else
if (areVector) {
int svgIndex = m_fileFormat->findText("svg");
if (svgIndex < 0)
m_fileFormat->addItem("svg");
m_fileFormat->setCurrentIndex(m_fileFormat->findText("svg"));
m_fileFormat->setEnabled(false);
onFormatSelected("svg");
}
#endif
m_srcFilePaths = fps;
if (m_srcFilePaths.size() == 1) {
setWindowTitle(tr("Convert 1 Level"));
m_fromFld->setEnabled(true);
m_toFld->setEnabled(true);
m_fileNameFld->setEnabled(true);
m_fromFld->setText("");
m_toFld->setText("");
TLevelP levelTmp;
TLevelReaderP lrTmp = TLevelReaderP(fps[0]);
if (lrTmp) {
levelTmp = lrTmp->loadInfo();
TLevel::Table *t = levelTmp->getTable();
if (!t->empty()) {
TFrameId start = t->begin()->first;
TFrameId end = t->rbegin()->first;
if (start.getNumber() > 0)
m_fromFld->setText(QString::number(start.getNumber()));
if (end.getNumber() > 0)
m_toFld->setText(QString::number(end.getNumber()));
}
}
//m_fromFld->setText("1");
//m_toFld->setText(QString::number(levelTmp->getFrameCount()==-2?1:levelTmp->getFrameCount()));
m_fileNameFld->setText(QString::fromStdString(fps[0].getName()));
} else {
setWindowTitle(tr("Convert %1 Levels").arg(m_srcFilePaths.size()));
m_fromFld->setText("");
m_toFld->setText("");
m_fileNameFld->setText("");
m_fromFld->setEnabled(false);
m_toFld->setEnabled(false);
m_fileNameFld->setEnabled(false);
}
m_saveInFileFld->setPath(toQString(fps[0].getParentDir()));
//if (m_unpaintedFolder->getPath()==SameAsPainted)
// m_unpaintedFolder->setPath(toQString(fps[0].getParentDir()));
m_palettePath->setPath(CreateNewPalette);
//m_fileFormat->setCurrentIndex(areFullcolor?0:m_fileFormat->findText("tif"));
}
//-------------------------------------------------------------------
Convert2Tlv *ConvertPopup::makeTlvConverter(const TFilePath &sourceFilePath)
{
ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
TFilePath unpaintedfilePath;
if (m_tlvMode->currentText() == TlvMode_PaintedFromTwoImages) {
QString suffixString = m_unpaintedSuffix->text();
TFilePath unpaintedFolder;
if (m_unpaintedFolder->getPath() == SameAsPainted)
unpaintedFolder = sourceFilePath.getParentDir();
else
unpaintedFolder = TFilePath(m_unpaintedFolder->getPath().toStdString());
string basename = sourceFilePath.getName() + suffixString.toStdString();
unpaintedfilePath = sc->decodeFilePath(sourceFilePath.withParentDir(unpaintedFolder).withName(basename));
}
int from = -1, to = -1;
if (m_srcFilePaths.size() > 1) {
from = m_fromFld->getValue();
to = m_toFld->getValue();
}
TFilePath palettePath;
if (m_palettePath->getPath() != CreateNewPalette)
palettePath = sc->decodeFilePath(TFilePath(m_palettePath->getPath().toStdString()));
TFilePath fn = sc->decodeFilePath(sourceFilePath);
TFilePath out = sc->decodeFilePath(TFilePath(m_saveInFileFld->getPath().toStdWString()));
Convert2Tlv *converter = new Convert2Tlv(fn, unpaintedfilePath, out,
m_fileNameFld->text(), from, to,
m_applyAutoclose->isChecked(),
palettePath,
m_tolerance->getValue(),
m_antialias->currentIndex(),
m_antialiasIntensity->getValue(),
getTlvMode() == TlvMode_UnpaintedFromNonAA);
return converter;
}
//-------------------------------------------------------------------
void ConvertPopup::convertToTlv(bool toPainted)
{
#ifdef CICCIO
ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
bool doAutoclose = false;
QApplication::setOverrideCursor(Qt::WaitCursor);
int i, totFrames = 0, skipped = 0;
TFilePath::setUnderscoreFormatAllowed(!m_unpaintedSuffix->text().contains('_'));
vector<Convert2Tlv *> converters;
for (i = 0; i < m_srcFilePaths.size(); i++) {
Convert2Tlv *converter = makeTlvConverter(m_srcFilePaths[i]);
if (TSystem::doesExistFileOrLevel(converter->m_levelOut)) {
if (m_skip->isChecked()) {
MsgBox(INFORMATION, QString(tr("Level ")) + QString::fromStdWString(converter->m_levelOut.withoutParentDir().getWideString()) + QString(tr(" already exists; skipped")));
delete converter;
skipped++;
continue;
} else
TSystem::removeFileOrLevel(converter->m_levelOut);
}
totFrames += converter->getFramesToConvertCount();
converters.push_back(converter);
}
if (converters.empty()) {
QApplication::restoreOverrideCursor();
TFilePath::setUnderscoreFormatAllowed(false);
return;
}
ProgressDialog pb("", tr("Cancel"), 0, totFrames);
int j, l, k = 0;
for (i = 0; i < converters.size(); i++) {
string errorMessage;
if (!converters[i]->init(errorMessage)) {
converters[i]->abort();
MsgBox(CRITICAL, QString::fromStdString(errorMessage));
delete converters[i];
converters[i] = 0;
skipped++;
continue;
}
int count = converters[i]->getFramesToConvertCount();
pb.setLabelText(tr("Generating level ") + toQString(converters[i]->m_levelOut));
pb.show();
for (j = 0; j < count; j++) {
string errorMessage = "";
if (!converters[i]->convertNext(errorMessage) || pb.wasCanceled()) {
for (l = i; l < converters.size(); l++) {
converters[l]->abort();
delete converters[i];
converters[i] = 0;
}
if (errorMessage != "")
MsgBox(CRITICAL, QString::fromStdString(errorMessage));
QApplication::restoreOverrideCursor();
FileBrowser::refreshFolder(m_srcFilePaths[0].getParentDir());
TFilePath::setUnderscoreFormatAllowed(false);
return;
}
pb.setValue(++k);
MsgBox(INFORMATION, QString(tr("Level ")) + QString::fromStdWString(m_srcFilePaths[i].withoutParentDir().getWideString()) + QString(tr(" converted to tlv.")));
}
TFilePath levelOut(converters[i]->m_levelOut);
delete converters[i];
IconGenerator::instance()->invalidate(levelOut);
converters[i] = 0;
}
QApplication::restoreOverrideCursor();
pb.hide();
if (m_srcFilePaths.size() == 1) {
if (skipped == 0)
MsgBox(INFORMATION, tr("Level %1 converted to TLV Format").arg(QString::fromStdWString(m_srcFilePaths[0].withoutParentDir().getWideString())));
else
MsgBox(WARNING, tr("Warning: Level %1 NOT converted to TLV Format").arg(QString::fromStdWString(m_srcFilePaths[0].withoutParentDir().getWideString())));
} else
MsgBox(skipped == 0 ? INFORMATION : WARNING, tr("Converted %1 out of %2 Levels to TLV Format").arg(QString::number(m_srcFilePaths.size() - skipped)).arg(QString::number(m_srcFilePaths.size())));
FileBrowser::refreshFolder(m_srcFilePaths[0].getParentDir());
TFilePath::setUnderscoreFormatAllowed(false);
#endif
}
//-----------------------------------------------------------------------------
TFilePath ConvertPopup::getDestinationFilePath(const TFilePath &sourceFilePath)
{
// Build the DECODED output folder path
TFilePath destFolder = sourceFilePath.getParentDir();
if (!m_saveInFileFld->getPath().isEmpty()) {
TFilePath dir(m_saveInFileFld->getPath().toStdWString());
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
destFolder = scene->decodeFilePath(dir);
}
// Build the output level name
const QString &fldName = m_fileNameFld->text();
const std::string &ext = m_fileFormat->currentText().toStdString();
const std::wstring &name = fldName.isEmpty() ? sourceFilePath.getWideName() : fldName.toStdWString();
TFilePath destName = TFilePath(name).withType(ext);
if (TFileType::isLevelFilePath(sourceFilePath) && !TFileType::isLevelExtension(ext))
destName = destName.withFrame(TFrameId::EMPTY_FRAME); // use the '..' format to denote an output level
// Merge the two
return destFolder + destName;
}
//-----------------------------------------------------------------------------
TPalette *ConvertPopup::readUserProvidedPalette() const
{
if (m_palettePath->getPath() == CreateNewPalette || m_fileFormat->currentText() != TlvExtension)
return 0;
ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
TFilePath palettePath = sc->decodeFilePath(TFilePath(m_palettePath->getPath().toStdString()));
TPalette *palette = 0;
try {
TIStream is(palettePath);
is >> palette;
// note! refCount==0
} catch (...) {
MsgBox(WARNING, tr("Warning: Can't read palette '%1' ").arg(m_palettePath->getPath()));
if (palette) {
delete palette;
palette = 0;
}
}
return palette;
}
//-----------------------------------------------------------------------------
void ConvertPopup::getFrameRange(const TFilePath &sourceFilePath,
TFrameId &from, TFrameId &to)
{
from = to = TFrameId();
if (!TFileType::isLevelFilePath(sourceFilePath))
return;
TLevelReaderP lr(sourceFilePath);
if (!lr)
return;
TLevelP level = lr->loadInfo();
if (level->begin() == level->end())
return;
TFrameId firstFrame = from = level->begin()->first,
lastFrame = to = (--level->end())->first;
if (m_srcFilePaths.size() == 1) {
// Just one level - consider from/to input fields, too
TFrameId fid;
bool ok;
fid = TFrameId(m_fromFld->text().toInt(&ok));
if (ok && fid > from)
from = tcrop(fid, firstFrame, lastFrame);
fid = TFrameId(m_toFld->text().toInt(&ok));
if (ok && fid < to)
to = tcrop(fid, firstFrame, lastFrame);
}
}
//-----------------------------------------------------------------------------
bool ConvertPopup::checkParameters() const
{
if (m_srcFilePaths.size() == 1 && m_fileNameFld->text().isEmpty()) {
MsgBox(WARNING, tr("No output filename specified: please choose a valid level name."));
return false;
}
if (m_fileFormat->currentText() == TlvExtension) {
if (m_tlvMode->currentText() == TlvMode_PaintedFromTwoImages) {
if (m_unpaintedSuffix->text() == "") {
MsgBox(WARNING, tr("No unpainted suffix specified: cannot convert."));
return false;
}
}
}
if (m_palettePath->getPath() == CreateNewPalette || m_fileFormat->currentText() != TlvExtension) {
TPalette *palette = readUserProvidedPalette();
delete palette;
// note: don't keep a reference to the palette because that can not be used by the Convert2Tlv class (that requires a TFilePath instead)
}
return true;
}
//--------------------------------------------------
void ConvertPopup::apply()
{
// if parameters are not ok do nothing and don't close the dialog
if (!checkParameters())
return;
/*--- envにパラメータを記憶 ---*/
ConvertPopupFileFormat = m_fileFormat->currentText().toStdString();
TPixel32 bgCol = m_bgColorField->getColor();
ConvertPopupBgColorR = (int)bgCol.r;
ConvertPopupBgColorG = (int)bgCol.g;
ConvertPopupBgColorB = (int)bgCol.b;
ConvertPopupBgColorA = (int)bgCol.m;
ConvertPopupSkipExisting = (int)m_skip->isChecked();
ConvertPopupRemoveDot = (int)m_removeDotBeforeFrameNumber->isChecked();
ConvertPopupSaveToNopaint = (int)m_saveBackupToNopaint->isChecked();
// parameters are ok: close the dialog first
close();
m_isConverting = true;
m_progressDialog->show();
m_notifier->reset();
QApplication::setOverrideCursor(Qt::WaitCursor);
m_converter = new Converter(this);
#if QT_VERSION >= 0x050000
bool ret = connect(m_converter, SIGNAL(finished()), this, SLOT(onConvertFinished()));
#else
int ret = connect(m_converter, SIGNAL(finished()), this, SLOT(onConvertFinished()));
#endif
Q_ASSERT(ret);
// TODO: salvare il vecchio stato
if (m_fileFormat->currentText() == TlvExtension && m_tlvMode->currentText() == TlvMode_PaintedFromTwoImages) {
if (!m_unpaintedSuffix->text().contains('_'))
TFilePath::setUnderscoreFormatAllowed(true);
}
// start converting. Conversion end is handled by onConvertFinished() slot
m_converter->start();
}
//------------------------------------------------------------------
void ConvertPopup::onConvertFinished()
{
m_isConverting = false;
TFilePath dstFilePath(m_saveInFileFld->getPath().toStdWString());
if (dstFilePath == m_srcFilePaths[0].getParentDir())
FileBrowser::refreshFolder(dstFilePath);
m_progressDialog->close();
QApplication::restoreOverrideCursor();
int errorCount = m_notifier->getErrorCount();
int skippedCount = m_converter->getSkippedCount();
if (errorCount > 0) {
if (skippedCount > 0)
MsgBox(CRITICAL, tr("Convert completed with %1 error(s) and %2 level(s) skipped").arg(errorCount).arg(skippedCount));
else
MsgBox(CRITICAL, tr("Convert completed with %1 error(s) ").arg(errorCount));
} else if (skippedCount > 0) {
MsgBox(WARNING, tr("%1 level(s) skipped").arg(skippedCount));
}
/*
if (m_srcFilePaths.size()==1)
{
if (skipped==0)
MsgBox(INFORMATION, tr("Level %1 converted to TLV Format").arg(QString::fromStdWString(m_srcFilePaths[0].withoutParentDir().getWideString())));
else
MsgBox(WARNING, tr("Warning: Level %1 NOT converted to TLV Format").arg(QString::fromStdWString(m_srcFilePaths[0].withoutParentDir().getWideString())));
}
else
MsgBox(skipped==0?INFORMATION:WARNING, tr("Converted %1 out of %2 Levels to TLV Format").arg( QString::number(m_srcFilePaths.size()-skipped)).arg(QString::number(m_srcFilePaths.size())));
*/
//TFilePath parentDir = m_srcFilePaths[0].getParentDir();
//FileBrowser::refreshFolder(parentDir);
delete m_converter;
m_converter = 0;
}
//-------------------------------------------------------------------
void ConvertPopup::onLevelConverted(const TFilePath &fullPath)
{
IconGenerator::instance()->invalidate(fullPath);
}
//-------------------------------------------------------------------
TPropertyGroup *ConvertPopup::getFormatProperties(const string &ext)
{
if (m_formatProperties.contains(ext))
return m_formatProperties[ext];
TPropertyGroup *props = Tiio::makeWriterProperties(ext);
m_formatProperties[ext] = props;
return props;
}
//-------------------------------------------------------------------
void ConvertPopup::onOptionsClicked()
{
string ext = m_fileFormat->currentText().toStdString();
TPropertyGroup *props = getFormatProperties(ext);
openFormatSettingsPopup(this, ext, props, m_srcFilePaths.size() == 1 ? m_srcFilePaths[0] : TFilePath());
}
//-------------------------------------------------------------------
void ConvertPopup::onFormatChanged(const QString &ext)
{
if (ext == QString("avi") ||
ext == QString("tzp") ||
ext == TlvExtension) {
m_removeDotBeforeFrameNumber->setChecked(false);
m_removeDotBeforeFrameNumber->setEnabled(false);
} else {
m_removeDotBeforeFrameNumber->setEnabled(true);
if (ext == QString("tga"))
m_removeDotBeforeFrameNumber->setChecked(true);
}
}
//-------------------------------------------------------------------
bool ConvertPopup::isSaveTlvBackupToNopaintActive()
{
return m_fileFormat->currentText() == TlvExtension /*-- tlvが選択されている --*/
&& m_tlvMode->currentText() == TlvMode_Unpainted /*-- Unpainted Tlvが選択されている --*/
&& m_saveBackupToNopaint->isChecked(); /*-- Save Backup to "nopaint" Folder オプションが有効 --*/
}
//=============================================================================
// ConvertPopupCommand
//-----------------------------------------------------------------------------
OpenPopupCommandHandler<ConvertPopup> openConvertPopup(MI_ConvertFiles);