Blob Blame Raw


#include "toonzqt/infoviewer.h"
#include "toonzqt/intfield.h"
#include "tsystem.h"
#include "tlevel.h"
#include "tpalette.h"
#include "tlevel_io.h"
#include "tsound_io.h"
#include "tiio.h"
#include "tstream.h"
#include "ttoonzimage.h"
#include "trasterimage.h"
#include "tvectorimage.h"
#include "toonz/toonzscene.h"
#include "toonzqt/gutil.h"
#include "toonzqt/dvdialog.h"
#include "toutputproperties.h"
#include "toonz/sceneproperties.h"
#include "toonz/tcamera.h"
#include "toonz/levelset.h"
#include "tcontenthistory.h"
#include "tfiletype.h"
#include <QSlider>
#include <QLabel>
#include <QTextEdit>
#include <QDateTime>

using namespace DVGui;

//----------------------------------------------------------------

class InfoViewerImp
{
public:
	enum {
		eFullpath = 0,
		eFileType,
		eFrames,
		eOwner,
		eSize,
		eCreated,
		eModified,
		eLastAccess,
		eImageSize,
		eSaveBox,
		eBitsSample,
		eSamplePixel,
		eDpi,
		eOrientation,
		eCompression,
		eQuality,
		eSmoothing,
		eCodec,
		eAlphaChannel,
		eByteOrdering,
		eHPos,
		ePalettePages,
		ePaletteStyles,
		eCamera,
		eCameraDpi,
		eFrameCount,
		eLevelCount,
		eOutputPath,
		eEndianess,

		//sound info
		eLength,
		eChannels,
		eSampleRate,
		eSampleSize,
		eHowMany
	};

	TFilePath m_path;
	TLevelP m_level;
	std::vector<TFrameId> m_fids;
	QStringList m_formats;
	int m_currentIndex;
	int m_frameCount;
	TPalette *m_palette;
	QLabel m_framesLabel;
	IntField m_framesSlider;
	std::vector<std::pair<QLabel *, QLabel *>> m_labels;
	QLabel m_historyLabel;
	QTextEdit m_history;
	Separator m_separator1, m_separator2;
	void setFileInfo(const TFileStatus &status);
	void setImageInfo();
	void setSoundInfo();
	//void cleanFileInfo();
	void cleanLevelInfo();
	void setToonzSceneInfo();
	void setPaletteInfo();
	void setGeneralFileInfo(const TFilePath &path);
	QString getTypeString();
	void onSliderChanged();
	InfoViewerImp();
	~InfoViewerImp();
	void clear();
	bool setLabel(TPropertyGroup *pg, int index, std::string type);
	void create(int index, QString str);
	void loadPalette(const TFilePath &path);

	inline void setVal(int index, const QString &str)
	{
		m_labels[index].second->setText(str);
	}

public slots:

	bool setItem(const TLevelP &level, TPalette *palette, const TFilePath &path);
};

//----------------------------------------------------------------

InfoViewer::InfoViewer(QWidget *parent)
	: Dialog()
	, m_imp(new InfoViewerImp())
{
	setWindowTitle(tr("File Info"));
	setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
	//setAttribute(Qt::WA_DeleteOnClose);

	m_parent = parent;

	int i;
	for (i = 0; i < (int)m_imp->m_labels.size(); i++) {
		addWidgets(m_imp->m_labels[i].first, m_imp->m_labels[i].second);
		if (i == InfoViewerImp::eLastAccess)
			addWidget(&m_imp->m_separator1);
	}

	addWidget(&m_imp->m_separator2);
	addWidget(&m_imp->m_historyLabel);
	addWidget(&m_imp->m_history);

	addWidgets(&m_imp->m_framesLabel, &m_imp->m_framesSlider);

	connect(&m_imp->m_framesSlider, SIGNAL(valueChanged(bool)), this, SLOT(onSliderChanged(bool)));
	hide();
}

InfoViewer::~InfoViewer()
{
}

//----------------------------------------------------------------

void InfoViewer::hideEvent(QHideEvent *)
{
	m_imp->m_level = TLevelP();

	if (m_parent) {
		m_parent->setWindowModality(Qt::ApplicationModal);
		//setWindowModality(Qt::NonModal);
	}
}

void InfoViewer::showEvent(QShowEvent *)
{
	if (m_parent) {
		m_parent->setWindowModality(Qt::NonModal);
		//setWindowModality(Qt::WindowModal);
	}
}

//----------------------------------------------------------------
void InfoViewer::onSliderChanged(bool)
{
	m_imp->onSliderChanged();
}

//----------------------------------------------------------------

void InfoViewerImp::onSliderChanged()
{
	if (m_framesSlider.getValue() - 1 == m_currentIndex)
		return;

	m_currentIndex = m_framesSlider.getValue() - 1;
	setImageInfo();
}

//----------------------------------------------------------------

namespace
{
void setLabelStyle(QLabel *l)
{
	l->setFrameStyle(QFrame::StyledPanel);
	l->setStyleSheet("color: rgb(0, 0, 200);");
}
}

//----------------------------------------------------------------

void InfoViewerImp::create(int index, QString str)
{
	m_labels[index] = std::pair<QLabel *, QLabel *>(new QLabel(str), new QLabel(""));
	setLabelStyle(m_labels[index].first);
}

//----------------------------------------------------------------

InfoViewerImp::InfoViewerImp()
	: m_palette(0), m_framesLabel("Current Frame: "), m_framesSlider(), m_history(), m_historyLabel("File History")
{
	setLabelStyle(&m_framesLabel);

	TLevelReader::getSupportedFormats(m_formats);
	TSoundTrackReader::getSupportedFormats(m_formats);

	m_labels.resize(eHowMany);

	create(eFullpath, QObject::tr("Fullpath:     "));
	create(eFileType, QObject::tr("File Type:    "));
	create(eFrames, QObject::tr("Frames:       "));
	create(eOwner, QObject::tr("Owner:        "));
	create(eSize, QObject::tr("Size:         "));

	create(eCreated, QObject::tr("Created:      "));
	create(eModified, QObject::tr("Modified:     "));
	create(eLastAccess, QObject::tr("Last Access:  "));

	//level info

	create(eImageSize, QObject::tr("Image Size:   "));
	create(eSaveBox, QObject::tr("SaveBox:      "));
	create(eBitsSample, QObject::tr("Bits/Sample:  "));
	create(eSamplePixel, QObject::tr("Sample/Pixel: "));
	create(eDpi, QObject::tr("Dpi:          "));
	create(eOrientation, QObject::tr("Orientation:  "));
	create(eCompression, QObject::tr("Compression:  "));
	create(eQuality, QObject::tr("Quality:      "));
	create(eSmoothing, QObject::tr("Smoothing:    "));
	create(eCodec, QObject::tr("Codec:        "));
	create(eAlphaChannel, QObject::tr("Alpha Channel:"));
	create(eByteOrdering, QObject::tr("Byte Ordering:"));
	create(eHPos, QObject::tr("H Pos:"));
	create(ePalettePages, QObject::tr("Palette Pages:"));
	create(ePaletteStyles, QObject::tr("Palette Styles:"));

	create(eCamera, QObject::tr("Camera Size:      "));
	create(eCameraDpi, QObject::tr("Camera Dpi:       "));
	create(eFrameCount, QObject::tr("Number of Frames: "));
	create(eLevelCount, QObject::tr("Number of Levels: "));
	create(eOutputPath, QObject::tr("Output Path:      "));
	create(eEndianess, QObject::tr("Endianess:      "));

	//sound info
	create(eLength, QObject::tr("Length:       "));
	create(eChannels, QObject::tr("Channels: "));
	create(eSampleRate, QObject::tr("Sample Rate: "));
	create(eSampleSize, QObject::tr("Sample Size:      "));

	m_historyLabel.setStyleSheet("color: rgb(0, 0, 200);");
	m_history.setStyleSheet("font-size: 12px; font-family: \"courier\";");
	//m_history.setStyleSheet("font-family: \"courier\";");
	m_history.setReadOnly(true);
	m_history.setFixedWidth(490);
}

//----------------------------------------------------------------

void InfoViewerImp::clear()
{
	int i;

	for (i = 0; i < (int)m_labels.size(); i++)
		setVal(i, "");

	m_history.clear();
}

//----------------------------------------------------------------

InfoViewerImp::~InfoViewerImp()
{
	int i;
	for (i = 0; i < (int)m_labels.size(); i++) {
		delete m_labels[i].first;
		delete m_labels[i].second;
	}

	m_labels.clear();
}

//----------------------------------------------------------------

void InfoViewerImp::setFileInfo(const TFileStatus &status)
{
	//m_fPath.setText(status.
}

//----------------------------------------------------------------

QString InfoViewerImp::getTypeString()
{
	QString ext = QString::fromStdString(m_path.getType());

	if (ext == "tlv" || ext == "tzp" || ext == "tzu")
		return "Toonz Cmapped Raster Level";
	else if (ext == "pli" || ext == "svg")
		return "Toonz Vector Level";
	else if (ext == "mov" || ext == "avi" || ext == "3gp")
		return "Movie File";
	else if (ext == "tnz")
		return "Toonz Scene";
	else if (ext == "tab")
		return "Tab Scene";
	else if (ext == "plt")
		return "Toonz Palette";
	else if (ext == "wav" || ext == "aiff" || ext == "mp3")
		return "Audio File";
	else if (ext == "mesh")
		return "Toonz Mesh Level";
	else if (ext == "pic")
		return "Pic File";
	else if (Tiio::makeReader(ext.toStdString()))
		return (m_fids.size() == 1) ? "Single Raster Image" : "Raster Image Level";
	else if (ext == "psd")
		return "Photoshop Image";
	else
		return "Unmanaged File Type";
}

//----------------------------------------------------------------

void InfoViewerImp::setGeneralFileInfo(const TFilePath &path)
{
	QFileInfo fi = toQString(path);
	assert(fi.exists());

	setVal(eFullpath, fi.absoluteFilePath());
	setVal(eFileType, getTypeString());
	if (fi.owner() != "")
		setVal(eOwner, fi.owner());
	setVal(eSize, fileSizeString(fi.size()));
	setVal(eCreated, fi.created().toString());
	setVal(eModified, fi.lastModified().toString());
	setVal(eLastAccess, fi.lastRead().toString());
	m_separator1.show();
}

//----------------------------------------------------------------

bool InfoViewerImp::setLabel(TPropertyGroup *pg, int index, std::string type)
{
	TProperty *p = pg->getProperty(type);
	if (!p)
		return false;
	QString str = QString::fromStdString(p->getValueAsString());
	if (dynamic_cast<TBoolProperty *>(p))
		setVal(index, str == "0" ? "No" : "Yes");
	else
		setVal(index, str);
	return true;
}

//----------------------------------------------------------------

void InfoViewerImp::setImageInfo()
{
	if (m_path != TFilePath() && !m_fids.empty())
		setGeneralFileInfo(m_path.getType() == "tlv" || !m_path.isLevelName() ? m_path : m_path.withFrame(m_fids[m_currentIndex]));

	assert(m_level);

	setVal(eFrames, QString::number(m_level->getFrameCount()));

	TLevelReaderP lr(m_path);
	const TImageInfo *ii;
	try {
		ii = lr->getImageInfo(m_fids[m_currentIndex]);
	} catch (...) {
		return;
	}
	if (!m_fids.empty() && lr && ii) {
		setVal(eImageSize, QString::number(ii->m_lx) + " X " + QString::number(ii->m_ly));
		if (ii->m_x0 <= ii->m_x1)
			setVal(eSaveBox, "(" + QString::number(ii->m_x0) + ", " + QString::number(ii->m_y0) + ", " + QString::number(ii->m_x1) + ", " + QString::number(ii->m_y1) + ")");
		if (ii->m_bitsPerSample > 0)
			setVal(eBitsSample, QString::number(ii->m_bitsPerSample));
		if (ii->m_samplePerPixel > 0)
			setVal(eSamplePixel, QString::number(ii->m_samplePerPixel));
		if (ii->m_dpix > 0 || ii->m_dpiy > 0)
			setVal(eDpi, "(" + QString::number(ii->m_dpix) + ", " + QString::number(ii->m_dpiy) + ")");
		TPropertyGroup *pg = ii->m_properties;
		if (pg) {
			setLabel(pg, eOrientation, "Orientation");
			if (!setLabel(pg, eCompression, "Compression") && !setLabel(pg, eCompression, "Compression Type") && !setLabel(pg, eCompression, "RLE-Compressed"))
				setLabel(pg, eCompression, "File Compression");
			setLabel(pg, eQuality, "Quality");
			setLabel(pg, eSmoothing, "Smoothing");
			setLabel(pg, eCodec, "Codec");
			setLabel(pg, eAlphaChannel, "Alpha Channel");
			setLabel(pg, eByteOrdering, "Byte Ordering");
			setLabel(pg, eEndianess, "Endianess");
		}
	} else
		m_separator1.hide();

	const TContentHistory *ch = 0;
	if (lr)
		ch = lr->getContentHistory();

	if (ch) {
		QString str = ch->serialize();
		str = str.remove('\n');
		str = str.remove(QChar(0));
		str = str.replace("||", "\n");
		str = str.remove('|');
		m_history.setPlainText(str);
	}

	TImageP img = m_level->frame(m_fids[m_currentIndex]);
	TToonzImageP timg = (TToonzImageP)img;
	TRasterImageP rimg = (TRasterImageP)img;
	TVectorImageP vimg = (TVectorImageP)img;

	if (img) {
		TRect r = convert(timg->getBBox());
		if (r.x0 <= r.x1)
			setVal(eSaveBox, "(" + QString::number(r.x0) + ", " + QString::number(r.y0) + ", " + QString::number(r.x1) + ", " + QString::number(r.y1) + ")");
	}

	double dpix, dpiy;

	if (timg) {
		//setVal(eHPos, QString::number(timg->gethPos()));
		timg->getDpi(dpix, dpiy);
		setVal(eDpi, "(" + QString::number(dpix) + ", " + QString::number(dpiy) + ")");
		TDimension dim = timg->getRaster()->getSize();
		setVal(eImageSize, QString::number(dim.lx) + " X " + QString::number(dim.ly));
		m_palette = timg->getPalette();
	} else if (rimg) {
		rimg->getDpi(dpix, dpiy);
		setVal(eDpi, "(" + QString::number(dpix) + ", " + QString::number(dpiy) + ")");
		TDimension dim = rimg->getRaster()->getSize();
		setVal(eImageSize, QString::number(dim.lx) + " X " + QString::number(dim.ly));
	} else if (vimg)
		m_palette = vimg->getPalette();

	//TImageP img = m_level->frame(m_fids[m_currentIndex]);
}

//----------------------------------------------------------------

void InfoViewerImp::setSoundInfo()
{
	if (m_path != TFilePath())
		setGeneralFileInfo(m_path);
	TSoundTrackP sndTrack;
	try {
		TSoundTrackReaderP sr(m_path);
		if (sr)
			sndTrack = sr->load();
	} catch (...) {
		return;
	}
	if (!sndTrack)
		return;

	int seconds = sndTrack->getDuration();
	int minutes = seconds / 60;
	seconds = seconds % 60;
	QString label;
	if (minutes > 0)
		label += QString::number(minutes) + " min ";
	label += QString::number(seconds) + " sec";
	setVal(eLength, label);

	label = QString::number(sndTrack->getChannelCount());
	setVal(eChannels, label);

	TUINT32 sampleRate = sndTrack->getSampleRate();
	label = QString::number(sampleRate / 1000) + " KHz";
	setVal(eSampleRate, label);

	label = QString::number(sndTrack->getBitPerSample()) + " bit";
	setVal(eSampleSize, label);
}

//----------------------------------------------------------------

void InfoViewerImp::cleanLevelInfo()
{
}

//----------------------------------------------------------------

void InfoViewer::setItem(const TLevelP &level, TPalette *palette, const TFilePath &path)
{
	if (m_imp->setItem(level, palette, path))
		show();
	else
		hide();
}

//----------------------------------------------------------------

void InfoViewerImp::setToonzSceneInfo()
{
	ToonzScene scene;
	try {
		scene.loadNoResources(m_path);
	} catch (...) {
		return;
	}

	TCamera *cam = scene.getCurrentCamera();
	if (!cam)
		return;

	TContentHistory *ch = scene.getContentHistory();
	if (ch) {
		QString str = ch->serialize();
		str = str.remove('\n');
		str = str.remove(QChar(0));
		str = str.replace("||", "\n");
		str = str.remove('|');
		m_history.setPlainText(str);
	}

	TLevelSet *set = scene.getLevelSet();
	TSceneProperties *prop = scene.getProperties();
	TOutputProperties *oprop = prop->getOutputProperties();

	setVal(eCamera, QString::number(cam->getRes().lx) + " X " + QString::number(cam->getRes().ly));
	setVal(eCameraDpi, QString::number(cam->getDpi().x) + ", " + QString::number(cam->getDpi().y));
	setVal(eFrameCount, QString::number(scene.getFrameCount()));
	if (set)
		setVal(eLevelCount, QString::number(set->getLevelCount()));

	if (oprop)
		setVal(eOutputPath, toQString(oprop->getPath()));
}

//----------------------------------------------------------------

void InfoViewerImp::setPaletteInfo()
{
	if (!m_palette)
		return;

	setVal(ePalettePages, QString::number(m_palette->getPageCount()));
	setVal(ePaletteStyles, QString::number(m_palette->getStyleCount()));
}

//----------------------------------------------------------------

void InfoViewerImp::loadPalette(const TFilePath &path)
{
	TIStream is(path);
	if (is) {
		TPersist *p = 0;
		is >> p;
		m_palette = dynamic_cast<TPalette *>(p);
	}
}

//----------------------------------------------------------------

bool InfoViewerImp::setItem(const TLevelP &level, TPalette *palette, const TFilePath &path)
{
	int i;
	clear();

	m_path = path;
	m_level = level;
	m_fids.clear();
	m_currentIndex = 0;
	m_palette = palette;
	m_framesLabel.hide();
	m_framesSlider.hide();
	m_separator1.hide();
	m_separator2.hide();

	QString ext = QString::fromStdString(m_path.getType());

	if (m_path != TFilePath() && !m_formats.contains(ext) && !Tiio::makeReader(m_path.getType())) {
		// e' un file non  di immagine (plt, tnz, ...)
		assert(!m_level);

		if (!TSystem::doesExistFileOrLevel(m_path)) {
			DVGui::warning(QObject::tr("The file %1 does not exist.").arg(QString::fromStdWString(path.getWideString())));

			return false;
		}

		setGeneralFileInfo(m_path);

		if (ext == "plt") {
			assert(!m_level && !m_palette);
			loadPalette(m_path);
		} else if (ext == "tnz")
			setToonzSceneInfo();
	} else if (TFileType::getInfo(m_path) == TFileType::AUDIO_LEVEL) {
		setSoundInfo();
	} else {
		if (ext == "tlv")
			loadPalette(m_path.withNoFrame().withType("tpl"));

		if (!m_level) {
			assert(m_path != TFilePath());
			TLevelReaderP lr;
			try {
				lr = TLevelReaderP(m_path);
			} catch (...) {
				return false;
			}
			if (lr) {
				try {
					m_level = lr->loadInfo();
				} catch (...) {
					return false;
				}
			}
		}

		if (m_level) {
			// Image or level of images case

			// TLVs are not intended as movie file here (why?). Neither are those
			bool isMovieFile =
				(ext != "tlv" && m_formats.contains(ext) && !m_path.isLevelName());

			m_frameCount = m_level->getFrameCount();
			assert(m_frameCount);
			m_fids.resize(m_frameCount);
			TLevel::Iterator it = m_level->begin();
			for (i = 0; it != m_level->end(); ++it, ++i)
				m_fids[i] = it->first;

			if (m_frameCount > 1 && !isMovieFile) {
				m_framesSlider.setRange(1, m_frameCount);
				m_framesSlider.setValue(0);
				m_framesSlider.show();
				m_framesLabel.show();
			}

			setImageInfo();
		} else
			return false;
	}

	if (m_palette)
		setPaletteInfo();

	for (i = 0; i < (int)m_labels.size(); i++)
		if (m_labels[i].second->text() == "")
			m_labels[i].first->hide(), m_labels[i].second->hide();
		else
			m_labels[i].first->show(), m_labels[i].second->show();

	if (m_history.toPlainText() == "") {
		m_separator2.hide();
		m_historyLabel.hide();
		m_history.hide();
	} else {
		m_separator2.show();
		m_historyLabel.show();
		m_history.show();
	}

	return true;
}