Convert scene to/from using Implicit Holds
This commit is contained in:
parent
dddc869de7
commit
aa87e6fe5a
6 changed files with 175 additions and 0 deletions
|
@ -588,6 +588,9 @@ in TXsheetImp.
|
|||
void notifyStageObjectAdded(const TStageObjectId id);
|
||||
bool isReferenceManagementIgnored(TDoubleParam *);
|
||||
|
||||
void convertToImplicitHolds();
|
||||
void convertToExplicitHolds();
|
||||
|
||||
protected:
|
||||
bool checkCircularReferences(TXsheet *childCandidate);
|
||||
|
||||
|
|
|
@ -2021,6 +2021,10 @@ void MainWindow::defineActions() {
|
|||
createMenuXsheetAction(MI_RemoveEmptyColumns,
|
||||
QT_TR_NOOP("Remove Empty Columns"), "",
|
||||
"remove_empty_columns");
|
||||
createMenuXsheetAction(MI_ConvertToImplicitHolds,
|
||||
QT_TR_NOOP("Convert to use Implicit Holds"), "", "");
|
||||
createMenuXsheetAction(MI_ConvertToExplicitHolds,
|
||||
QT_TR_NOOP("Convert to use Explicit Holds"), "", "");
|
||||
createMenuXsheetAction(MI_LipSyncPopup,
|
||||
QT_TR_NOOP("&Apply Lip Sync to Column"), "Alt+L",
|
||||
"dialogue");
|
||||
|
|
|
@ -433,6 +433,9 @@ void TopBar::loadMenubar() {
|
|||
addMenuItem(sceneMenu, MI_LipSyncPopup);
|
||||
sceneMenu->addSeparator();
|
||||
addMenuItem(sceneMenu, MI_RemoveEmptyColumns);
|
||||
sceneMenu->addSeparator();
|
||||
addMenuItem(sceneMenu, MI_ConvertToImplicitHolds);
|
||||
addMenuItem(sceneMenu, MI_ConvertToExplicitHolds);
|
||||
|
||||
// Menu' LEVEL
|
||||
QMenu *levelMenu = addMenu(ShortcutTree::tr("Level"), m_menuBar);
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#define MI_ImportMagpieFile "MI_ImportMagpieFile"
|
||||
#define MI_NewNoteLevel "MI_NewNoteLevel"
|
||||
#define MI_RemoveEmptyColumns "MI_RemoveEmptyColumns"
|
||||
#define MI_ConvertToImplicitHolds "MI_ConvertToImplicitHolds"
|
||||
#define MI_ConvertToExplicitHolds "MI_ConvertToExplicitHolds"
|
||||
#define MI_NewProject "MI_NewProject"
|
||||
#define MI_OpenRecentProject "MI_OpenRecentProject"
|
||||
#define MI_LoadProject "MI_LoadProject"
|
||||
|
|
|
@ -1158,6 +1158,53 @@ public:
|
|||
|
||||
//============================================================
|
||||
|
||||
static void convertHoldType(int holdType) {
|
||||
TTool::Application *app = TTool::getApplication();
|
||||
TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
|
||||
|
||||
if (!xsh) return;
|
||||
|
||||
int answer = DVGui::MsgBox(
|
||||
QString(QObject::tr("Converting scene to use %1 Holds can only be undone "
|
||||
"using 'Revert Scene'. Save before converting.\nDo "
|
||||
"you want to continue?")
|
||||
.arg(holdType == 0 ? QObject::tr("Implicit")
|
||||
: QObject::tr("Explicit"))),
|
||||
QObject::tr("Continue"), QObject::tr("Cancel"), 1);
|
||||
|
||||
if (answer == 0 || answer == 2) return;
|
||||
|
||||
QAction *action =
|
||||
CommandManager::instance()->getAction(MI_ToggleImplicitHold);
|
||||
if (holdType == 0) {
|
||||
xsh->convertToImplicitHolds();
|
||||
if (action && !action->isChecked()) action->trigger();
|
||||
} else {
|
||||
xsh->convertToExplicitHolds();
|
||||
if (action && action->isChecked()) action->trigger();
|
||||
}
|
||||
|
||||
app->getCurrentScene()->setDirtyFlag();
|
||||
|
||||
app->getCurrentXsheet()->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
class ConvertToImplicitHoldsCommand final : public MenuItemHandler {
|
||||
public:
|
||||
ConvertToImplicitHoldsCommand()
|
||||
: MenuItemHandler(MI_ConvertToImplicitHolds) {}
|
||||
void execute() override { XshCmd::convertHoldType(0); }
|
||||
} ConvertToImplicitHoldsCommand;
|
||||
|
||||
class ConvertToExplicitHoldsCommand final : public MenuItemHandler {
|
||||
public:
|
||||
ConvertToExplicitHoldsCommand()
|
||||
: MenuItemHandler(MI_ConvertToExplicitHolds) {}
|
||||
void execute() override { XshCmd::convertHoldType(1); }
|
||||
} ConvertToExplicitHoldsCommand;
|
||||
|
||||
//============================================================
|
||||
|
||||
} // namespace XshCmd
|
||||
|
||||
//*****************************************************************************
|
||||
|
|
|
@ -1965,3 +1965,119 @@ ExpressionReferenceMonitor *TXsheet::getExpRefMonitor() const {
|
|||
return m_imp->m_expRefMonitor;
|
||||
}
|
||||
//---------------------------------------------------------
|
||||
|
||||
void TXsheet::convertToImplicitHolds() {
|
||||
int cols = getColumnCount();
|
||||
if (!cols) return;
|
||||
|
||||
set<const TXsheet *> visitedXshs;
|
||||
visitedXshs.insert(this);
|
||||
|
||||
for (int c = 0; c < cols; c++) {
|
||||
TXshColumn *column = getColumn(c);
|
||||
if (!column || column->isEmpty()) continue;
|
||||
|
||||
TXshCellColumn *cc = column->getCellColumn();
|
||||
if (!cc || cc->getColumnType() == TXshColumn::ColumnType::eSoundTextType ||
|
||||
cc->getColumnType() == TXshColumn::ColumnType::eSoundType)
|
||||
continue;
|
||||
|
||||
int r0, r1;
|
||||
if (!cc->getRange(r0, r1)) continue;
|
||||
|
||||
bool stopFrameSet = false;
|
||||
TXshCell prevCell;
|
||||
for (int r = r0; r <= r1; r++) {
|
||||
TXshCell cell = cc->getCell(r);
|
||||
|
||||
if (cell.isEmpty()) {
|
||||
if (!stopFrameSet) {
|
||||
// Set a stop frame if one hasn't been set yet
|
||||
prevCell = TXshCell(prevCell.m_level, TFrameId::STOP_FRAME);
|
||||
cc->setCell(r, prevCell);
|
||||
stopFrameSet = true;
|
||||
}
|
||||
} else {
|
||||
TXshLevel *level = cell.m_level.getPointer();
|
||||
if (level && level->getChildLevel()) {
|
||||
TXsheet *childXsh = level->getChildLevel()->getXsheet();
|
||||
if (visitedXshs.count(childXsh) == 0) {
|
||||
visitedXshs.insert(childXsh);
|
||||
childXsh->convertToImplicitHolds();
|
||||
}
|
||||
}
|
||||
|
||||
// Keep 1st instance of new cells, replace duplicates with an empty
|
||||
// frame
|
||||
if (cell != prevCell)
|
||||
prevCell = cell;
|
||||
else if (cc->getColumnType() == TXshColumn::ColumnType::eZeraryFxType) {
|
||||
std::vector<TXshCell> cells;
|
||||
cells.push_back(TXshCell(0, TFrameId::EMPTY_FRAME));
|
||||
cc->setCells(r, 1, &cells[0]);
|
||||
} else
|
||||
cc->setCell(r, TXshCell(0, TFrameId::EMPTY_FRAME));
|
||||
|
||||
stopFrameSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a final stop frame
|
||||
cc->setCell(r1 + 1, TXshCell(prevCell.m_level, TFrameId::STOP_FRAME));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
void TXsheet::convertToExplicitHolds() {
|
||||
int cols = getColumnCount();
|
||||
if (!cols) return;
|
||||
|
||||
set<const TXsheet *> visitedXshs;
|
||||
visitedXshs.insert(this);
|
||||
|
||||
for (int c = 0; c < cols; c++) {
|
||||
TXshColumn *column = getColumn(c);
|
||||
if (!column || column->isEmpty()) continue;
|
||||
|
||||
TXshCellColumn *cc = column->getCellColumn();
|
||||
if (!cc || cc->getColumnType() == TXshColumn::ColumnType::eSoundTextType ||
|
||||
cc->getColumnType() == TXshColumn::ColumnType::eSoundType)
|
||||
continue;
|
||||
|
||||
int r0, r1;
|
||||
if (!cc->getRange(r0, r1)) continue;
|
||||
|
||||
int frameCount = getFrameCount() - 1;
|
||||
bool stopFrameSet = false;
|
||||
TXshCell prevCell;
|
||||
|
||||
r1 = std::max(r1, frameCount);
|
||||
|
||||
for (int r = r0; r <= r1; r++) {
|
||||
TXshCell cell = cc->getCell(r);
|
||||
|
||||
TXshLevel *level = cell.m_level.getPointer();
|
||||
if (level && level->getChildLevel()) {
|
||||
TXsheet *childXsh = level->getChildLevel()->getXsheet();
|
||||
if (visitedXshs.count(childXsh) == 0) {
|
||||
visitedXshs.insert(childXsh);
|
||||
childXsh->convertToImplicitHolds();
|
||||
}
|
||||
}
|
||||
|
||||
if (cell != prevCell && !cell.isEmpty()) prevCell = cell;
|
||||
|
||||
if (cell.getFrameId().isStopFrame()) {
|
||||
prevCell = TXshCell(0, TFrameId::EMPTY_FRAME);
|
||||
if (cc->getColumnType() == TXshColumn::ColumnType::eZeraryFxType) {
|
||||
std::vector<TXshCell> cells;
|
||||
cells.push_back(prevCell);
|
||||
cc->setCells(r, 1, &cells[0]);
|
||||
} else
|
||||
cc->setCell(r, TXshCell(prevCell));
|
||||
} else
|
||||
cc->setCell(r, prevCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue