#include "castviewer.h"
// Tnz6 includes
#include "castselection.h"
#include "tapp.h"
#include "menubarcommandids.h"
#include "floatingpanelcommand.h"
#include "iocommand.h"
#include "filmstripcommand.h"
#include "flipbook.h"
// TnzLib includes
#include "toonz/tscenehandle.h"
#include "toonz/txsheethandle.h"
#include "toonz/txshlevelhandle.h"
#include "toonz/levelset.h"
#include "toonz/toonzscene.h"
#include "toonz/levelset.h"
#include "toonz/txshsimplelevel.h"
#include "toonz/txshleveltypes.h"
// TnzQt includes
#include "toonzqt/dvdialog.h"
#include "toonzqt/gutil.h"
#include "toonzqt/trepetitionguard.h"
#include "toonzqt/icongenerator.h"
#include "toonzqt/infoviewer.h"
#include "historytypes.h"
// TnzCore includes
#include "tundo.h"
#include "tfiletype.h"
#include "tsystem.h"
// Qt includes
#include <QDrag>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QDragLeaveEvent>
#include <QHeaderView>
#include <QPainter>
#include <QBoxLayout>
#include <QLabel>
#include <QByteArray>
#include <QDesktopServices>
#include <QUrl>
#include <QMenu>
#include <QDir>
const char *AudioFolderName = "Audio";
using namespace DVGui;
namespace
{
//Se il widget del cast viewer viene spostato in toonzqt (e quindi fatto dipendere dallo sceneHandle)
//questo undo puo' essere spostato in un nuovo file levelsetcommand in toonzlib.
class MoveLevelToFolderUndo : public TUndo
{
TLevelSet *m_levelSet;
std::wstring m_levelName;
TFilePath m_oldFolder;
TFilePath m_newFolder;
public:
MoveLevelToFolderUndo(TLevelSet *levelSet, std::wstring levelName, TFilePath newFolder)
: m_levelSet(levelSet), m_levelName(levelName), m_newFolder(newFolder)
{
TXshLevel *level = m_levelSet->getLevel(m_levelName);
m_oldFolder = m_levelSet->getFolder(level);
}
void undo() const
{
TXshLevel *level = m_levelSet->getLevel(m_levelName);
m_levelSet->moveLevelToFolder(m_oldFolder, level);
TApp::instance()->getCurrentScene()->notifyCastChange();
}
void redo() const
{
TXshLevel *level = m_levelSet->getLevel(m_levelName);
m_levelSet->moveLevelToFolder(m_newFolder, level);
TApp::instance()->getCurrentScene()->notifyCastChange();
}
int getSize() const
{
return sizeof(*this);
}
QString getHistoryString()
{
return QObject::tr("Move Level to Cast Folder");
}
};
}
//=============================================================================
//
// CastTreeViewer
//
//-----------------------------------------------------------------------------
CastTreeViewer::CastTreeViewer(QWidget *parent)
: QTreeWidget(parent), m_dropTargetItem(0)
{
setObjectName("OnePixelMarginFrame");
//setObjectName("BrowserTreeView");
//setStyleSheet("#BrowserTreeView {border: 0px; margin: 1px; qproperty-autoFillBackground: true;}");
header()->close();
setIconSize(QSize(21, 17));
setUniformRowHeights(true);
// m_treeViewer->setColumnCount(1);
setAcceptDrops(true);
connect(
this, SIGNAL(itemChanged(QTreeWidgetItem *, int)),
this, SLOT(onItemChanged(QTreeWidgetItem *, int)));
connect(
this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
this, SLOT(onFolderChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
connect(
TApp::instance()->getCurrentScene(), SIGNAL(sceneSwitched()),
this, SLOT(rebuildCastTree()));
connect(
TApp::instance()->getCurrentScene(), SIGNAL(castFolderAdded(const TFilePath &)),
this, SLOT(onCastFolderAdded(const TFilePath &)));
connect(
TApp::instance()->getCurrentScene(), SIGNAL(nameSceneChanged()),
this, SLOT(onSceneNameChanged()));
//Connect all possible changes that can alter the
//bottom horizontal scrollbar to resize contents...
connect(
this, SIGNAL(expanded(const QModelIndex &)),
this, SLOT(resizeToConts()));
connect(
this, SIGNAL(collapsed(const QModelIndex &)),
this, SLOT(resizeToConts()));
connect(
this->model(), SIGNAL(layoutChanged()),
this, SLOT(resizeToConts()));
rebuildCastTree();
}
//-----------------------------------------------------------------------------
//!Resizes viewport to contents
void CastTreeViewer::resizeToConts(void)
{
resizeColumnToContents(0);
}
//-----------------------------------------------------------------------------
void CastTreeViewer::resizeEvent(QResizeEvent *event)
{
resizeColumnToContents(0);
QTreeView::resizeEvent(event);
}
//-----------------------------------------------------------------------------
TLevelSet *CastTreeViewer::getLevelSet()
{
return TApp::instance()->getCurrentScene()->getScene()->getLevelSet();
}
//-----------------------------------------------------------------------------
void CastTreeViewer::enableCommands()
{
enableCommand(this, MI_Clear, &CastTreeViewer::deleteFolder);
}
//-----------------------------------------------------------------------------
void CastTreeViewer::onFolderChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
// rende la selezione corrente; serve per intercettare il comando MI_Clear
makeCurrent();
}
//-----------------------------------------------------------------------------
void CastTreeViewer::populateFolder(QTreeWidgetItem *folder)
{
TFilePath folderPath(folder->data(1, Qt::DisplayRole).toString().toStdWString());
std::vector<TFilePath> folders;
getLevelSet()->listFolders(folders, folderPath);
int i;
for (i = 0; i < (int)folders.size(); i++) {
TFilePath fp = folders[i];
QString fpQstr = QString::fromStdWString(fp.getWideString());
QString name = QString::fromStdWString(fp.withoutParentDir().getWideString());
QTreeWidgetItem *child = new QTreeWidgetItem((QTreeWidgetItem *)0, QStringList(name) << fpQstr);
if (name != AudioFolderName)
child->setFlags(child->flags() | Qt::ItemIsEditable);
folder->addChild(child);
populateFolder(child);
}
}
//-----------------------------------------------------------------------------
void CastTreeViewer::onSceneNameChanged()
{
QTreeWidgetItem *root = topLevelItem(0);
if (!root)
return;
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
QString rootName = QString("Root");
if (scene) {
std::wstring name = (scene->isUntitled()) ? L"Untitled" : scene->getSceneName();
rootName = rootName.fromStdWString(name);
}
root->setText(0, rootName);
}
//-----------------------------------------------------------------------------
void CastTreeViewer::onCastFolderAdded(const TFilePath &path)
{
QTreeWidgetItem *root = topLevelItem(0)->child(0);
assert(root->data(1, Qt::DisplayRole).toString() == toQString(getLevelSet()->getDefaultFolder()));
QString childName = QString::fromStdWString(path.getWideName());
QString childPathQstr = QString::fromStdWString(path.getWideString());
QTreeWidgetItem *childItem = new QTreeWidgetItem(root, QStringList(childName) << childPathQstr);
childItem->setFlags(childItem->flags() | Qt::ItemIsEditable);
root->addChild(childItem);
setCurrentItem(childItem);
}
//-----------------------------------------------------------------------------
void CastTreeViewer::rebuildCastTree()
{
clear();
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
QString rootName = QString("Root");
if (scene) {
std::wstring name = (scene->isUntitled()) ? L"Untitled" : scene->getSceneName();
rootName = rootName.fromStdWString(name);
}
QTreeWidgetItem *root = new QTreeWidgetItem((QTreeWidgetItem *)0, QStringList(rootName));
static QPixmap clapboard(":Resources/clapboard.png");
root->setIcon(0, clapboard);
insertTopLevelItem(0, root);
populateFolder(root);
}
//-----------------------------------------------------------------------------
QSize CastTreeViewer::sizeHint() const
{
return QSize(100, 100);
}
//-----------------------------------------------------------------------------
void CastTreeViewer::paintEvent(QPaintEvent *event)
{
QTreeWidget::paintEvent(event);
QPainter p(viewport());
if (m_dropTargetItem) {
p.setPen(QColor(50, 105, 200));
p.drawRect(visualItemRect(m_dropTargetItem).adjusted(0, 0, -1, 0));
}
}
//-----------------------------------------------------------------------------
void CastTreeViewer::dragEnterEvent(QDragEnterEvent *e)
{
m_dropFilePath = TFilePath();
if (acceptResourceOrFolderDrop(e->mimeData()->urls())) {
if (e->mimeData()->urls().size() != 1)
return;
TFilePath path(e->mimeData()->urls()[0].toLocalFile().toStdWString());
if (path.getType() == "tnz")
m_dropFilePath = path;
else
return;
}
if (!e->mimeData()->hasFormat("application/vnd.toonz.levels") && m_dropFilePath == TFilePath())
return;
m_dropTargetItem = itemAt(e->pos());
if (m_dropTargetItem && m_dropTargetItem->data(0, Qt::DisplayRole).toString() == AudioFolderName)
m_dropTargetItem = 0;
e->acceptProposedAction();
viewport()->update();
}
//-----------------------------------------------------------------------------
void CastTreeViewer::dragMoveEvent(QDragMoveEvent *event)
{
if (!event->mimeData()->hasFormat("application/vnd.toonz.levels") || m_dropFilePath != TFilePath())
return;
m_dropTargetItem = itemAt(event->pos());
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
QString rootName = QString("Root");
if (scene) {
std::wstring name = (scene->isUntitled()) ? L"Untitled" : scene->getSceneName();
rootName = rootName.fromStdWString(name);
}
if (m_dropTargetItem && m_dropTargetItem->data(0, Qt::DisplayRole).toString() == AudioFolderName ||
m_dropFilePath != TFilePath() && m_dropTargetItem->data(0, Qt::DisplayRole).toString() == rootName)
m_dropTargetItem = 0;
if (!m_dropTargetItem)
event->ignore();
else
event->acceptProposedAction();
viewport()->update();
}
//-----------------------------------------------------------------------------
void CastTreeViewer::dropEvent(QDropEvent *event)
{
m_dropTargetItem = 0;
if (m_dropFilePath != TFilePath()) {
IoCmd::loadScene(m_dropFilePath);
m_dropFilePath = TFilePath();
m_dropTargetItem = 0;
update();
return;
}
if (!event->mimeData()->hasFormat("application/vnd.toonz.levels"))
return;
m_dropTargetItem = itemAt(event->pos());
if (!m_dropTargetItem)
return;
TFilePath folderPath(m_dropTargetItem->data(1, Qt::DisplayRole).toString().toStdWString());
m_dropTargetItem = 0;
update();
if (folderPath.getName() == AudioFolderName) {
event->ignore();
return;
}
event->acceptProposedAction();
TLevelSet *levelSet = getLevelSet();
const CastItems *castItems = dynamic_cast<const CastItems *>(event->mimeData());
assert(castItems);
if (!castItems)
return;
int i;
TUndoManager::manager()->beginBlock();
for (i = 0; i < castItems->getItemCount(); i++) {
CastItem *item = castItems->getItem(i);
if (LevelCastItem *li = dynamic_cast<LevelCastItem *>(item)) {
TXshLevel *level = li->getLevel();
std::wstring levelName = level->getName();
MoveLevelToFolderUndo *undo = new MoveLevelToFolderUndo(levelSet, levelName, folderPath);
levelSet->moveLevelToFolder(folderPath, level);
TUndoManager::manager()->add(undo);
} else if (SoundCastItem *si = dynamic_cast<SoundCastItem *>(item)) {
}
}
TUndoManager::manager()->endBlock();
emit itemMovedToFolder();
}
//-----------------------------------------------------------------------------
void CastTreeViewer::dragLeaveEvent(QDragLeaveEvent *event)
{
m_dropTargetItem = 0;
m_dropFilePath = TFilePath();
update();
}
//-----------------------------------------------------------------------------
void CastTreeViewer::onItemChanged(QTreeWidgetItem *item, int column)
{
if (column != 0)
return;
if (item->isSelected()) {
TFilePath oldPath(item->data(1, Qt::DisplayRole).toString().toStdWString());
TFilePath newPath = getLevelSet()->renameFolder(oldPath, item->text(0).toStdWString());
item->setText(1, QString::fromStdWString(newPath.getWideString()));
}
}
//-----------------------------------------------------------------------------
TFilePath CastTreeViewer::getCurrentFolder() const
{
if (!currentItem())
return TFilePath();
QVariant data = currentItem()->data(1, Qt::DisplayRole);
if (data == QVariant())
return TFilePath();
return TFilePath(data.toString().toStdWString());
}
//-----------------------------------------------------------------------------
void CastTreeViewer::folderUp()
{
QTreeWidgetItem *item = currentItem();
if (item && item->parent() != (QTreeWidgetItem *)0)
setCurrentItem(item->parent());
}
//-----------------------------------------------------------------------------
void CastTreeViewer::newFolder()
{
QTreeWidgetItem *parentItem = currentItem();
if (parentItem == (QTreeWidgetItem *)0)
return;
QString parentName = parentItem->data(0, Qt::DisplayRole).toString();
if (parentName == AudioFolderName)
return;
TFilePath parentPath = TFilePath(parentItem->data(1, Qt::DisplayRole).toString().toStdWString());
QString childName("New Folder");
TFilePath childPath = parentPath + childName.toStdWString();
QString childPathQstr = QString::fromStdWString(childPath.getWideString());
QTreeWidgetItem *childItem = new QTreeWidgetItem(parentItem, QStringList(childName) << childPathQstr);
childItem->setFlags(childItem->flags() | Qt::ItemIsEditable);
parentItem->addChild(childItem);
setCurrentItem(childItem);
editItem(childItem);
TLevelSet *levelSet = TApp::instance()->getCurrentScene()->getScene()->getLevelSet();
levelSet->createFolder(parentPath, childName.toStdWString());
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
}
//-----------------------------------------------------------------------------
void CastTreeViewer::deleteFolder()
{
QTreeWidgetItem *item = currentItem();
if (!item || !item->parent())
return;
QString itemName = item->data(0, Qt::DisplayRole).toString();
if (itemName == AudioFolderName)
return;
int ret = DVGui::MsgBox(tr("Delete folder ") + item->text(0) + "?", tr("Yes"), tr("No"), 1);
if (ret == 2 || ret == 0)
return;
QTreeWidgetItem *parentItem = item->parent();
TFilePath childPath(item->data(1, Qt::DisplayRole).toString().toStdWString());
TLevelSet *levelSet = TApp::instance()->getCurrentScene()->getScene()->getLevelSet();
levelSet->removeFolder(childPath);
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
parentItem->removeChild(item);
setCurrentItem(parentItem);
}
//=============================================================================
//
// CastBrowser
//
//-----------------------------------------------------------------------------
#if QT_VERSION >= 0x050500
CastBrowser::CastBrowser(QWidget *parent, Qt::WindowFlags flags)
#else
CastBrowser::CastBrowser(QWidget *parent, Qt::WFlags flags)
#endif
: QSplitter(parent)
, m_treeViewer(0)
, m_folderName(0)
, m_itemViewer(0)
, m_castItems(new CastItems())
{
// style sheet
setObjectName("CastBrowser");
setFrameStyle(QFrame::StyledPanel);
setStyleSheet("QSplitter::handle {height:4px;}");
setStyleSheet("#CastBrowser { margin:1px;border:0px }");
m_treeViewer = new CastTreeViewer(this);
m_treeViewer->resize(300, m_treeViewer->size().height());
QFrame *box = new QFrame(this);
box->setFrameStyle(QFrame::StyledPanel);
QVBoxLayout *boxLayout = new QVBoxLayout(box);
boxLayout->setMargin(0);
boxLayout->setSpacing(0);
m_folderName = new QLabel("", box);
m_folderName->setFrameStyle(QFrame::StyledPanel);
m_folderName->setStyleSheet("border-bottom: 1px solid black");
m_itemViewer = new DvItemViewer(box, false, true, DvItemViewer::Cast);
DvItemViewerPanel *viewerPanel = m_itemViewer->getPanel();
viewerPanel->setMissingTextColor(QColor(200, 0, 0));
CastSelection *castSelection = new CastSelection();
castSelection->setBrowser(this);
viewerPanel->setSelection(castSelection);
viewerPanel->addColumn(DvItemListModel::FrameCount, 50);
m_itemViewer->setModel(this);
DvItemViewerTitleBar *titleBar = new DvItemViewerTitleBar(m_itemViewer, box);
//titleBar->hide();
DvItemViewerButtonBar *buttonBar = new DvItemViewerButtonBar(m_itemViewer, box);
boxLayout->addWidget(m_folderName);
boxLayout->addWidget(titleBar);
boxLayout->addWidget(m_itemViewer);
boxLayout->addWidget(buttonBar);
boxLayout->setAlignment(buttonBar, Qt::AlignBottom);
box->setLayout(boxLayout);
addWidget(m_treeViewer);
addWidget(box);
setStretchFactor(1, 2);
TSceneHandle *sceneHandle = TApp::instance()->getCurrentScene();
connect(
sceneHandle, SIGNAL(sceneSwitched()),
this, SLOT(refresh()));
connect(
sceneHandle, SIGNAL(castChanged()),
this, SLOT(refresh()));
TXsheetHandle *xhseetHandle = TApp::instance()->getCurrentXsheet();
connect(xhseetHandle, SIGNAL(xsheetChanged()), m_itemViewer, SLOT(update()));
connect(buttonBar, SIGNAL(folderUp()), m_treeViewer, SLOT(folderUp()));
connect(buttonBar, SIGNAL(newFolder()), m_treeViewer, SLOT(newFolder()));
connect(m_treeViewer, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
this, SLOT(folderChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
connect(m_treeViewer, SIGNAL(itemMovedToFolder()),
this, SLOT(refresh()));
}
//-----------------------------------------------------------------------------
CastBrowser::~CastBrowser()
{
}
//-----------------------------------------------------------------------------
void CastBrowser::sortByDataModel(DataType dataType, bool isDiscendent)
{
if (dataType != getCurrentOrderType()) {
//Sort by another dataType
int i;
for (i = 1; i < m_castItems->getItemCount(); i++) {
int index = i;
while (index > 0 && compareData(dataType, index - 1, index) > 0) {
m_castItems->swapItem(index - 1, index);
index = index - 1;
}
}
setIsDiscendentOrder(true);
setOrderType(dataType);
}
//Sort by order (invert current)
if (isDiscendentOrder() != isDiscendent) {
setIsDiscendentOrder(isDiscendent);
std::vector<CastItem *> items;
int i = 0;
for (i; i < m_castItems->getItemCount(); i++)
items.push_back(m_castItems->getItem(i)->clone());
m_castItems->clear();
i = items.size() - 1;
for (i; i >= 0; i--)
m_castItems->addItem(items[i]);
}
m_itemViewer->getPanel()->update();
}
//-----------------------------------------------------------------------------
void CastBrowser::folderChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
refresh();
}
//-----------------------------------------------------------------------------
void CastBrowser::refresh()
{
if (isHidden())
return;
refreshData();
m_itemViewer->refresh();
}
//-----------------------------------------------------------------------------
/*
void CastBrowser::getLevels(std::vector<TXshLevel*> &levels) const
{
TLevelSet *levelSet = CastTreeViewer::getLevelSet();
TFilePath folder = m_treeViewer->getCurrentFolder();
if(folder != TFilePath())
levelSet->listLevels(levels, folder);
else
levelSet->listLevels(levels);
}
*/
//-----------------------------------------------------------------------------
void CastBrowser::refreshData()
{
m_castItems->clear();
TLevelSet *levelSet = CastTreeViewer::getLevelSet();
TFilePath folder = m_treeViewer->getCurrentFolder();
m_folderName->setText(toQString(folder));
std::vector<TXshLevel *> levels;
if (folder != TFilePath())
levelSet->listLevels(levels, folder);
else
levelSet->listLevels(levels);
int i;
for (i = 0; i < (int)levels.size(); i++) {
if (levels[i]->getSimpleLevel())
m_castItems->addItem(new LevelCastItem(levels[i], m_itemViewer->getPanel()->getIconSize()));
else if (levels[i]->getPaletteLevel())
m_castItems->addItem(new PaletteCastItem(levels[i]->getPaletteLevel(),
m_itemViewer->getPanel()->getIconSize()));
else if (levels[i]->getSoundLevel())
m_castItems->addItem(new SoundCastItem(levels[i]->getSoundLevel(),
m_itemViewer->getPanel()->getIconSize()));
}
}
//-----------------------------------------------------------------------------
int CastBrowser::getItemCount() const
{
return m_castItems->getItemCount();
}
//-----------------------------------------------------------------------------
QVariant CastBrowser::getItemData(int index, DataType dataType, bool isSelected)
{
if (index < 0 || index >= getItemCount())
return QVariant();
CastItem *item = m_castItems->getItem(index);
if (dataType == Name)
return item->getName();
else if (dataType == Thumbnail)
return item->getPixmap(isSelected);
else if (dataType == ToolTip)
return item->getToolTip();
else if (dataType == FrameCount)
return item->getFrameCount();
else if (dataType == VersionControlStatus) {
if (!item->exists())
return VC_Missing;
else
return 0; // No version control status displayed
} else
return QVariant();
}
//-----------------------------------------------------------------------------
/*
TXshSimpleLevel *CastBrowser::getSelectedSimpleLevel() const
{
const std::set<int> &indices = m_itemViewer->getSelectedIndices();
if(indices.empty()) return 0;
int index = *indices.begin();
std::vector<TXshLevel*> levels;
getLevels(levels);
if(index<0 || index>=(int)levels.size()) return 0;
TXshLevel*level = levels[index];
if(!level) return 0;
else return level->getSimpleLevel();
}
*/
//-----------------------------------------------------------------------------
void CastBrowser::startDragDrop()
{
TRepetitionGuard guard;
if (!guard.hasLock())
return;
const std::set<int> &indices = m_itemViewer->getSelectedIndices();
if (indices.empty())
return;
QDrag *drag = new QDrag(this);
QVariant v = getItemData(*indices.begin(), Thumbnail);
if (v != QVariant()) {
QPixmap dropThumbnail = v.value<QPixmap>();
if (!dropThumbnail.isNull())
drag->setPixmap(dropThumbnail);
}
drag->setMimeData(m_castItems->getSelectedItems(indices));
Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
}
//-----------------------------------------------------------------------------
bool CastBrowser::acceptDrop(const QMimeData *data) const
{
return acceptResourceOrFolderDrop(data->urls());
}
//-----------------------------------------------------------------------------
bool CastBrowser::drop(const QMimeData *data)
{
if (!acceptDrop(data))
return false;
if (data->hasUrls()) {
IoCmd::LoadResourceArguments args;
foreach (const QUrl &url, data->urls()) {
TFilePath fp(url.toLocalFile().toStdWString());
args.resourceDatas.push_back(fp);
}
args.castFolder = m_treeViewer->getCurrentFolder();
IoCmd::loadResources(args);
}
refresh();
return true;
}
//-----------------------------------------------------------------------------
QMenu *CastBrowser::getContextMenu(QWidget *parent, int index)
{
const std::set<int> &indices = m_itemViewer->getSelectedIndices();
if (indices.empty()) {
QMenu *menu = new QMenu(parent);
menu->addAction(CommandManager::instance()->getAction(MI_RemoveUnused));
return menu;
}
// controllo cosa c'e' nella selezione.
// => audioSelected, vectorLevelSelected, paletteSelected
std::set<int>::const_iterator it;
bool audioSelected = false;
bool paletteSelected = false;
bool vectorLevelSelected = false;
bool otherFileSelected = false;
int levelSelectedCount = 0;
for (it = indices.begin(); it != indices.end(); ++it) {
int index = *it;
if (index < 0 || index >= m_castItems->getItemCount())
continue; // non dovrebbe mai succedere
TXshSimpleLevel *sl = m_castItems->getItem(index)->getSimpleLevel();
if (!sl) {
if (m_castItems->getItem(index)->getPaletteLevel())
paletteSelected = true;
else
audioSelected = true;
continue;
}
levelSelectedCount++;
if (sl->getType() == PLI_XSHLEVEL)
vectorLevelSelected = true;
else
otherFileSelected = true;
}
QMenu *menu = new QMenu(parent);
CommandManager *cm = CommandManager::instance();
menu->addAction(cm->getAction(MI_LevelSettings));
menu->addAction(cm->getAction(MI_ExposeResource));
menu->addAction(cm->getAction(MI_ShowFolderContents));
menu->addAction(cm->getAction(MI_ViewFile));
menu->addAction(cm->getAction(MI_FileInfo));
if (audioSelected && !paletteSelected && !vectorLevelSelected && !otherFileSelected)
return menu;
// MI_EditLevel solo se e' stato selezionato un singolo diverso da livelli palette a livelli audio
if (indices.size() == 1 && !audioSelected && !paletteSelected)
menu->addAction(cm->getAction(MI_EditLevel));
if (!paletteSelected)
menu->addAction(cm->getAction(MI_SaveLevel));
menu->addSeparator();
// MI_ConvertToVectors se sono stati selezionati solo livelli non vettoriali
if (!audioSelected && !paletteSelected && !vectorLevelSelected)
menu->addAction(cm->getAction(MI_ConvertToVectors));
menu->addSeparator();
menu->addAction(cm->getAction(MI_RemoveLevel));
menu->addAction(cm->getAction(MI_RemoveUnused));
return menu;
}
//-----------------------------------------------------------------------------
void CastBrowser::expose()
{
std::set<int> selectedIndices = m_itemViewer->getPanel()->getSelectedIndices();
std::set<int>::iterator it = selectedIndices.begin();
TUndoManager::manager()->beginBlock();
for (it; it != selectedIndices.end(); it++) {
CastItem *item = m_castItems->getItem(*it);
TXshSimpleLevel *sl = item->getSimpleLevel();
TXshPaletteLevel *pl = item->getPaletteLevel();
TXshSoundLevel *soundl = item->getSoundLevel();
if (sl)
FilmstripCmd::moveToScene(sl);
else if (pl)
FilmstripCmd::moveToScene(pl);
else if (soundl)
FilmstripCmd::moveToScene(soundl);
}
TUndoManager::manager()->endBlock();
}
//-----------------------------------------------------------------------------
void CastBrowser::edit()
{
CastSelection *castSelection = dynamic_cast<CastSelection *>(TSelection::getCurrent());
if (!castSelection)
return;
std::vector<TXshLevel *> levels;
castSelection->getSelectedLevels(levels);
if ((int)levels.size() == 1) {
TXshLevel *l = levels[0];
if (l) {
TXshSimpleLevel *sl = l->getSimpleLevel();
if (sl) {
TApp::instance()->getCurrentLevel()->setLevel(sl);
return;
}
}
error(tr("It is not possible to edit the selected file."));
} else
error(tr("It is not possible to edit more than one file at once."));
}
//-----------------------------------------------------------------------------
void CastBrowser::showFolderContents()
{
int i = 0;
CastSelection *castSelection = dynamic_cast<CastSelection *>(TSelection::getCurrent());
if (!castSelection)
return;
std::vector<TXshLevel *> levels;
castSelection->getSelectedLevels(levels);
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
TFilePath folderPath, filePath;
for (i = 0; i < levels.size(); i++) {
folderPath = levels[i]->getPath().getParentDir();
filePath = levels[i]->getPath();
folderPath = scene->decodeFilePath(folderPath);
filePath = scene->decodeFilePath(filePath);
if (!TSystem::doesExistFileOrLevel(filePath)) {
error(tr("It is not possible to show the folder containing the selected file, as the file has not been saved yet."));
} else {
if (TSystem::isUNC(folderPath))
QDesktopServices::openUrl(QUrl(QString::fromStdWString(folderPath.getWideString())));
else
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdWString(folderPath.getWideString())));
}
}
}
//-----------------------------------------------------------------------------
void CastBrowser::viewFile()
{
CastSelection *castSelection = dynamic_cast<CastSelection *>(TSelection::getCurrent());
if (!castSelection)
return;
std::vector<TXshLevel *> levels;
castSelection->getSelectedLevels(levels);
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
TFilePath filePath;
if (levels.empty())
return;
int i = 0;
for (i = 0; i < levels.size(); i++) {
filePath = levels[i]->getPath();
filePath = scene->decodeFilePath(filePath);
if (!TSystem::doesExistFileOrLevel(filePath)) {
error(tr("It is not possible to view the selected file, as the file has not been saved yet."));
} else {
if (!TFileType::isViewable(TFileType::getInfo(filePath)))
return;
if (Preferences::instance()->isDefaultViewerEnabled() &&
(filePath.getType() == "mov" || filePath.getType() == "avi" || filePath.getType() == "3gp"))
QDesktopServices::openUrl(QUrl("file:///" + toQString(filePath)));
else
::viewFile(filePath);
}
}
}
//-----------------------------------------------------------------------------
void CastBrowser::viewFileInfo()
{
CastSelection *castSelection = dynamic_cast<CastSelection *>(TSelection::getCurrent());
if (!castSelection)
return;
std::vector<TXshLevel *> levels;
castSelection->getSelectedLevels(levels);
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
int i = 0;
if (levels.empty()) {
return;
} else {
for (i = 0; i < levels.size(); i++) {
TFilePath filePath;
filePath = levels[i]->getPath();
filePath = scene->decodeFilePath(filePath);
if (!TSystem::doesExistFileOrLevel(filePath)) {
error(tr("It is not possible to show the info of the selected file, as the file has not been saved yet."));
} else {
InfoViewer *infoViewer = 0;
infoViewer = new InfoViewer(this);
infoViewer->setItem(0, 0, filePath);
}
}
}
}
//=============================================================================
OpenFloatingPanel openCastPane(MI_OpenFileBrowser2, "SceneCast", QObject::tr("Scene Cast"));