Merge pull request #873 from manongjohn/convert_to_from_implicit

Convert scene to/from using Implicit Holds
This commit is contained in:
manongjohn 2022-01-23 12:05:18 -05:00 committed by GitHub
commit 9a35a9161f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 175 additions and 0 deletions

View file

@ -588,6 +588,9 @@ in TXsheetImp.
void notifyStageObjectAdded(const TStageObjectId id); void notifyStageObjectAdded(const TStageObjectId id);
bool isReferenceManagementIgnored(TDoubleParam *); bool isReferenceManagementIgnored(TDoubleParam *);
void convertToImplicitHolds();
void convertToExplicitHolds();
protected: protected:
bool checkCircularReferences(TXsheet *childCandidate); bool checkCircularReferences(TXsheet *childCandidate);

View file

@ -2021,6 +2021,10 @@ void MainWindow::defineActions() {
createMenuXsheetAction(MI_RemoveEmptyColumns, createMenuXsheetAction(MI_RemoveEmptyColumns,
QT_TR_NOOP("Remove Empty Columns"), "", QT_TR_NOOP("Remove Empty Columns"), "",
"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, createMenuXsheetAction(MI_LipSyncPopup,
QT_TR_NOOP("&Apply Lip Sync to Column"), "Alt+L", QT_TR_NOOP("&Apply Lip Sync to Column"), "Alt+L",
"dialogue"); "dialogue");

View file

@ -433,6 +433,9 @@ void TopBar::loadMenubar() {
addMenuItem(sceneMenu, MI_LipSyncPopup); addMenuItem(sceneMenu, MI_LipSyncPopup);
sceneMenu->addSeparator(); sceneMenu->addSeparator();
addMenuItem(sceneMenu, MI_RemoveEmptyColumns); addMenuItem(sceneMenu, MI_RemoveEmptyColumns);
sceneMenu->addSeparator();
addMenuItem(sceneMenu, MI_ConvertToImplicitHolds);
addMenuItem(sceneMenu, MI_ConvertToExplicitHolds);
// Menu' LEVEL // Menu' LEVEL
QMenu *levelMenu = addMenu(ShortcutTree::tr("Level"), m_menuBar); QMenu *levelMenu = addMenu(ShortcutTree::tr("Level"), m_menuBar);

View file

@ -44,6 +44,8 @@
#define MI_ImportMagpieFile "MI_ImportMagpieFile" #define MI_ImportMagpieFile "MI_ImportMagpieFile"
#define MI_NewNoteLevel "MI_NewNoteLevel" #define MI_NewNoteLevel "MI_NewNoteLevel"
#define MI_RemoveEmptyColumns "MI_RemoveEmptyColumns" #define MI_RemoveEmptyColumns "MI_RemoveEmptyColumns"
#define MI_ConvertToImplicitHolds "MI_ConvertToImplicitHolds"
#define MI_ConvertToExplicitHolds "MI_ConvertToExplicitHolds"
#define MI_NewProject "MI_NewProject" #define MI_NewProject "MI_NewProject"
#define MI_OpenRecentProject "MI_OpenRecentProject" #define MI_OpenRecentProject "MI_OpenRecentProject"
#define MI_LoadProject "MI_LoadProject" #define MI_LoadProject "MI_LoadProject"

View file

@ -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 } // namespace XshCmd
//***************************************************************************** //*****************************************************************************

View file

@ -1965,3 +1965,119 @@ ExpressionReferenceMonitor *TXsheet::getExpRefMonitor() const {
return m_imp->m_expRefMonitor; 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);
}
}
}