mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
Replace manual piece-data retain/release bookkeeping with shared copyable asset-reference handles. Pieces, models, selection, minifigs, thumbnails, and stored insertion previews retain their dependencies explicitly, while transient queries continue to borrow pointers. Separate registered lookup and acquisition from asynchronous load requests and explicit readiness waits. Keep loader-held references through work and notification delivery, resetting shared request handles on the UI thread and guarding callback-triggered library teardown. Validated with the Qt 6.10 debug build and 26 offscreen lifecycle checks, including cancellation, stale requests, copy/move operations, model/preview teardown, undo, project merge/export, and loader shutdown.
626 lines
15 KiB
C++
626 lines
15 KiB
C++
#include "lc_global.h"
|
|
#include "lc_timelinewidget.h"
|
|
#include "lc_model.h"
|
|
#include "piece.h"
|
|
#include "lc_piecedata.h"
|
|
#include "lc_mainwindow.h"
|
|
|
|
lcTimelineWidget::lcTimelineWidget(QWidget* Parent)
|
|
: QTreeWidget(Parent)
|
|
{
|
|
mCurrentStepItem = nullptr;
|
|
mIgnoreUpdates = false;
|
|
|
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
setDragEnabled(true);
|
|
setDragDropMode(QAbstractItemView::InternalMove);
|
|
setUniformRowHeights(true);
|
|
setHeaderHidden(true);
|
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
invisibleRootItem()->setFlags(invisibleRootItem()->flags() & ~Qt::ItemIsDropEnabled);
|
|
|
|
connect(this, &QTreeWidget::currentItemChanged, this, &lcTimelineWidget::CurrentItemChanged);
|
|
connect(this, &QTreeWidget::itemSelectionChanged, this, &lcTimelineWidget::ItemSelectionChanged);
|
|
connect(this, &QWidget::customContextMenuRequested, this, &lcTimelineWidget::CustomMenuRequested);
|
|
}
|
|
|
|
lcTimelineWidget::~lcTimelineWidget()
|
|
{
|
|
}
|
|
|
|
void lcTimelineWidget::CustomMenuRequested(QPoint Pos)
|
|
{
|
|
QMenu* Menu = new QMenu(this);
|
|
|
|
lcObject* FocusObject = gMainWindow->GetActiveModel()->GetFocusObject();
|
|
|
|
if (FocusObject && FocusObject->IsPiece())
|
|
{
|
|
lcPiece* Piece = (lcPiece*)FocusObject;
|
|
|
|
if (Piece->mPieceData->IsModel())
|
|
{
|
|
Menu->addAction(gMainWindow->mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]);
|
|
Menu->addAction(gMainWindow->mActions[LC_PIECE_VIEW_SELECTED_MODEL]);
|
|
Menu->addAction(gMainWindow->mActions[LC_PIECE_INLINE_SELECTED_MODELS]);
|
|
Menu->addSeparator();
|
|
}
|
|
}
|
|
|
|
Menu->addAction(gMainWindow->mActions[LC_TIMELINE_SET_CURRENT]);
|
|
Menu->addAction(gMainWindow->mActions[LC_TIMELINE_INSERT_BEFORE]);
|
|
Menu->addAction(gMainWindow->mActions[LC_TIMELINE_INSERT_AFTER]);
|
|
Menu->addAction(gMainWindow->mActions[LC_TIMELINE_DELETE]);
|
|
|
|
Menu->addSeparator();
|
|
|
|
Menu->addAction(gMainWindow->mActions[LC_TIMELINE_MOVE_SELECTION]);
|
|
Menu->addAction(gMainWindow->mActions[LC_TIMELINE_MOVE_SELECTION_BEFORE]);
|
|
Menu->addAction(gMainWindow->mActions[LC_TIMELINE_MOVE_SELECTION_AFTER]);
|
|
|
|
Menu->addSeparator();
|
|
|
|
Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_SELECTED]);
|
|
Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_UNSELECTED]);
|
|
Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_SELECTED]);
|
|
Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_ALL]);
|
|
|
|
Menu->exec(viewport()->mapToGlobal(Pos));
|
|
delete Menu;
|
|
}
|
|
|
|
void lcTimelineWidget::Update(bool Clear, bool UpdateItems)
|
|
{
|
|
if (mIgnoreUpdates)
|
|
return;
|
|
|
|
lcModel* Model = gMainWindow->GetActiveModel();
|
|
|
|
bool Blocked = blockSignals(true);
|
|
|
|
if (!Model)
|
|
{
|
|
mCurrentStepItem = nullptr;
|
|
mItems.clear();
|
|
clear();
|
|
blockSignals(Blocked);
|
|
return;
|
|
}
|
|
|
|
if (Clear)
|
|
{
|
|
mCurrentStepItem = nullptr;
|
|
mItems.clear();
|
|
clear();
|
|
}
|
|
|
|
lcStep LastStep = Model->GetLastStep();
|
|
if (Model->HasPieces())
|
|
LastStep++;
|
|
LastStep = lcMax(LastStep, Model->GetCurrentStep());
|
|
|
|
for (int TopLevelItemIdx = LastStep; TopLevelItemIdx < topLevelItemCount(); )
|
|
{
|
|
QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx);
|
|
|
|
while (StepItem->childCount())
|
|
{
|
|
QTreeWidgetItem* PieceItem = StepItem->child(0);
|
|
lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
mItems.remove(Piece);
|
|
delete PieceItem;
|
|
}
|
|
|
|
if (mCurrentStepItem == StepItem)
|
|
mCurrentStepItem = nullptr;
|
|
|
|
delete StepItem;
|
|
}
|
|
|
|
for (unsigned int TopLevelItemIdx = topLevelItemCount(); TopLevelItemIdx < LastStep; TopLevelItemIdx++)
|
|
{
|
|
QTreeWidgetItem* StepItem = new QTreeWidgetItem(this, QStringList(tr("Step %1").arg(TopLevelItemIdx + 1)));
|
|
StepItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
|
|
addTopLevelItem(StepItem);
|
|
StepItem->setExpanded(true);
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
|
|
QTreeWidgetItem* StepItem = nullptr;
|
|
int PieceItemIndex = 0;
|
|
lcStep Step = 0;
|
|
|
|
for (const std::unique_ptr<lcPiece>& Piece : Pieces)
|
|
{
|
|
while (Step != Piece->GetStepShow())
|
|
{
|
|
if (StepItem)
|
|
{
|
|
while (PieceItemIndex < StepItem->childCount())
|
|
{
|
|
QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex);
|
|
lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
auto RemoveIt = std::find_if(Pieces.begin(), Pieces.end(), [RemovePiece](const std::unique_ptr<lcPiece>& CheckPiece){ return CheckPiece.get() == RemovePiece; });
|
|
|
|
if (RemoveIt == Pieces.end())
|
|
{
|
|
mItems.remove(RemovePiece);
|
|
delete PieceItem;
|
|
}
|
|
else
|
|
{
|
|
PieceItem->parent()->removeChild(PieceItem);
|
|
topLevelItem(RemovePiece->GetStepShow() - 1)->addChild(PieceItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
Step++;
|
|
StepItem = topLevelItem(Step - 1);
|
|
PieceItemIndex = 0;
|
|
}
|
|
|
|
QTreeWidgetItem* PieceItem = mItems.value(Piece.get());
|
|
bool UpdateItem = UpdateItems;
|
|
|
|
if (StepItem)
|
|
{
|
|
if (!PieceItem)
|
|
{
|
|
PieceItem = new QTreeWidgetItem();
|
|
PieceItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
|
|
PieceItem->setData(0, Qt::UserRole, QVariant::fromValue<uintptr_t>((uintptr_t)Piece.get()));
|
|
StepItem->insertChild(PieceItemIndex, PieceItem);
|
|
mItems[Piece.get()] = PieceItem;
|
|
|
|
UpdateItem = true;
|
|
}
|
|
else
|
|
{
|
|
if (PieceItemIndex >= StepItem->childCount() || PieceItem != StepItem->child(PieceItemIndex))
|
|
{
|
|
QTreeWidgetItem* PieceParent = PieceItem->parent();
|
|
|
|
if (PieceParent)
|
|
PieceParent->removeChild(PieceItem);
|
|
|
|
StepItem->insertChild(PieceItemIndex, PieceItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (UpdateItem)
|
|
{
|
|
PieceItem->setText(0, Piece->mPieceData->m_strDescription);
|
|
|
|
int ColorIndex = Piece->GetColorIndex();
|
|
if (!mIcons.contains(ColorIndex))
|
|
{
|
|
int Size = rowHeight(indexFromItem(PieceItem));
|
|
|
|
QImage Image(Size, Size, QImage::Format_ARGB32);
|
|
Image.fill(0);
|
|
const lcVector4& Color = gColorList[ColorIndex].Value;
|
|
QPainter Painter(&Image);
|
|
Painter.setPen(Qt::darkGray);
|
|
Painter.setBrush(QColor::fromRgbF(Color[0], Color[1], Color[2]));
|
|
Painter.drawEllipse(0, 0, Size - 1, Size - 1);
|
|
|
|
mIcons[ColorIndex] = QIcon(QPixmap::fromImage(Image));
|
|
}
|
|
|
|
PieceItem->setIcon(0, mIcons[ColorIndex]);
|
|
|
|
QColor Color = palette().text().color();
|
|
|
|
if (Piece->mPieceData->mState == lcAssetState::Failed)
|
|
Color = QColor(208, 0, 0);
|
|
else if (Piece->IsHidden())
|
|
Color.setAlpha(128);
|
|
|
|
PieceItem->setForeground(0, Color);
|
|
}
|
|
|
|
PieceItem->setSelected(Piece->IsSelected());
|
|
PieceItemIndex++;
|
|
}
|
|
|
|
if (Step == 0)
|
|
{
|
|
Step = 1;
|
|
StepItem = topLevelItem(0);
|
|
}
|
|
|
|
while (Step <= LastStep && StepItem)
|
|
{
|
|
while (PieceItemIndex < StepItem->childCount())
|
|
{
|
|
QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex);
|
|
lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
|
|
mItems.remove(RemovePiece);
|
|
delete PieceItem;
|
|
}
|
|
|
|
Step++;
|
|
StepItem = topLevelItem(Step - 1);
|
|
PieceItemIndex = 0;
|
|
}
|
|
|
|
UpdateCurrentStepItem();
|
|
|
|
blockSignals(Blocked);
|
|
}
|
|
|
|
void lcTimelineWidget::UpdateCurrentStepItem()
|
|
{
|
|
lcModel* Model = gMainWindow->GetActiveModel();
|
|
lcStep CurrentStep = Model->GetCurrentStep();
|
|
QTreeWidgetItem* CurrentStepItem = topLevelItem(CurrentStep - 1);
|
|
|
|
if (CurrentStepItem != mCurrentStepItem)
|
|
{
|
|
if (mCurrentStepItem)
|
|
{
|
|
QFont Font = mCurrentStepItem->font(0);
|
|
Font.setBold(false);
|
|
mCurrentStepItem->setFont(0, Font);
|
|
}
|
|
|
|
if (CurrentStepItem)
|
|
{
|
|
QFont Font = CurrentStepItem->font(0);
|
|
Font.setBold(true);
|
|
CurrentStepItem->setFont(0, Font);
|
|
setCurrentItem(CurrentStepItem);
|
|
}
|
|
|
|
mCurrentStepItem = CurrentStepItem;
|
|
}
|
|
}
|
|
|
|
void lcTimelineWidget::UpdateSelection()
|
|
{
|
|
if (mIgnoreUpdates)
|
|
return;
|
|
|
|
QItemSelection ItemSelection;
|
|
|
|
for (int TopLevelItemIdx = 0; TopLevelItemIdx < topLevelItemCount(); TopLevelItemIdx++)
|
|
{
|
|
QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx);
|
|
|
|
for (int PieceItemIdx = 0; PieceItemIdx < StepItem->childCount(); PieceItemIdx++)
|
|
{
|
|
QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIdx);
|
|
lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
|
|
if (Piece && Piece->IsSelected())
|
|
{
|
|
QModelIndex Index = indexFromItem(PieceItem);
|
|
ItemSelection.select(Index, Index);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Blocked = blockSignals(true);
|
|
|
|
selectionModel()->select(ItemSelection, QItemSelectionModel::ClearAndSelect);
|
|
|
|
blockSignals(Blocked);
|
|
}
|
|
|
|
void lcTimelineWidget::InsertStepBefore()
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
if (CurrentItem->parent())
|
|
CurrentItem = CurrentItem->parent();
|
|
|
|
int Step = indexOfTopLevelItem(CurrentItem);
|
|
|
|
if (Step == -1)
|
|
return;
|
|
|
|
gMainWindow->GetActiveModel()->InsertStepAction(Step + 1);
|
|
}
|
|
|
|
void lcTimelineWidget::InsertStepAfter()
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
if (CurrentItem->parent())
|
|
CurrentItem = CurrentItem->parent();
|
|
|
|
int Step = indexOfTopLevelItem(CurrentItem);
|
|
|
|
if (Step == -1)
|
|
return;
|
|
|
|
gMainWindow->GetActiveModel()->InsertStepAction(Step + 2);
|
|
}
|
|
|
|
void lcTimelineWidget::RemoveStep()
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
if (CurrentItem->parent())
|
|
CurrentItem = CurrentItem->parent();
|
|
|
|
int Step = indexOfTopLevelItem(CurrentItem);
|
|
|
|
if (Step == -1)
|
|
return;
|
|
|
|
gMainWindow->GetActiveModel()->RemoveStepAction(Step + 1);
|
|
}
|
|
|
|
void lcTimelineWidget::MoveSelection()
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
if (CurrentItem->parent())
|
|
CurrentItem = CurrentItem->parent();
|
|
|
|
int Step = indexOfTopLevelItem(CurrentItem);
|
|
|
|
if (Step == -1)
|
|
return;
|
|
Step++;
|
|
|
|
const QList<QTreeWidgetItem*> SelectedItems = selectedItems();
|
|
|
|
for (QTreeWidgetItem* PieceItem : SelectedItems)
|
|
{
|
|
QTreeWidgetItem* Parent = PieceItem->parent();
|
|
|
|
if (!Parent)
|
|
continue;
|
|
|
|
int ChildIndex = Parent->indexOfChild(PieceItem);
|
|
CurrentItem->addChild(Parent->takeChild(ChildIndex));
|
|
}
|
|
|
|
UpdateModel();
|
|
|
|
lcModel* Model = gMainWindow->GetActiveModel();
|
|
|
|
if (Step > static_cast<int>(Model->GetCurrentStep()))
|
|
Model->SetCurrentStep(Step);
|
|
}
|
|
|
|
void lcTimelineWidget::MoveSelectionBefore()
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
if (CurrentItem->parent())
|
|
CurrentItem = CurrentItem->parent();
|
|
|
|
int Step = indexOfTopLevelItem(CurrentItem);
|
|
|
|
if (Step == -1)
|
|
return;
|
|
|
|
Step++;
|
|
|
|
lcModel* Model = gMainWindow->GetActiveModel();
|
|
|
|
Model->InsertStepAndMoveSelectedPieces(Step);
|
|
|
|
if (Step > static_cast<int>(Model->GetCurrentStep()))
|
|
Model->SetCurrentStep(Step);
|
|
}
|
|
|
|
void lcTimelineWidget::MoveSelectionAfter()
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
if (CurrentItem->parent())
|
|
CurrentItem = CurrentItem->parent();
|
|
|
|
int Step = indexOfTopLevelItem(CurrentItem);
|
|
|
|
if (Step == -1)
|
|
return;
|
|
|
|
Step += 2;
|
|
|
|
lcModel* Model = gMainWindow->GetActiveModel();
|
|
|
|
Model->InsertStepAndMoveSelectedPieces(Step);
|
|
|
|
if (Step > static_cast<int>(Model->GetCurrentStep()))
|
|
Model->SetCurrentStep(Step);
|
|
}
|
|
|
|
void lcTimelineWidget::SetCurrentStep()
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
if (CurrentItem->parent())
|
|
CurrentItem = CurrentItem->parent();
|
|
|
|
int Step = indexOfTopLevelItem(CurrentItem);
|
|
|
|
if (Step == -1)
|
|
return;
|
|
|
|
gMainWindow->GetActiveModel()->SetCurrentStep(Step + 1);
|
|
}
|
|
|
|
void lcTimelineWidget::CurrentItemChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous)
|
|
{
|
|
Q_UNUSED(Previous);
|
|
|
|
if (Current && !Current->parent())
|
|
SetCurrentStep();
|
|
}
|
|
|
|
void lcTimelineWidget::ItemSelectionChanged()
|
|
{
|
|
std::vector<lcObject*> Selection;
|
|
lcStep LastStep = 1;
|
|
const QList<QTreeWidgetItem*> SelectedItems = selectedItems();
|
|
|
|
for (QTreeWidgetItem* PieceItem : SelectedItems)
|
|
{
|
|
lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
if (Piece)
|
|
{
|
|
LastStep = lcMax(LastStep, Piece->GetStepShow());
|
|
Selection.emplace_back(Piece);
|
|
}
|
|
}
|
|
|
|
lcPiece* CurrentPiece = nullptr;
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
|
|
if (CurrentItem && CurrentItem->isSelected())
|
|
CurrentPiece = (lcPiece*)CurrentItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
|
|
bool Blocked = blockSignals(true);
|
|
mIgnoreUpdates = true;
|
|
lcModel* Model = gMainWindow->GetActiveModel();
|
|
|
|
if (LastStep > Model->GetCurrentStep())
|
|
{
|
|
Model->SetCurrentStep(LastStep);
|
|
UpdateCurrentStepItem();
|
|
}
|
|
|
|
Model->SetSelectionAndFocusAction(Selection, CurrentPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
|
|
|
|
mIgnoreUpdates = false;
|
|
blockSignals(Blocked);
|
|
|
|
UpdateSelection();
|
|
}
|
|
|
|
void lcTimelineWidget::dropEvent(QDropEvent* Event)
|
|
{
|
|
QTreeWidgetItem* DropItem = itemAt(Event->pos());
|
|
|
|
if (!DropItem)
|
|
return;
|
|
|
|
QList<QTreeWidgetItem*> SelectedItems = selectedItems();
|
|
clearSelection();
|
|
|
|
QTreeWidgetItem* ParentItem = DropItem->parent();
|
|
lcStep Step = indexOfTopLevelItem(ParentItem ? ParentItem : DropItem) + 1;
|
|
lcModel* Model = gMainWindow->GetActiveModel();
|
|
|
|
if (Step > Model->GetCurrentStep())
|
|
Model->SetCurrentStep(Step);
|
|
|
|
auto SortItems = [this](QTreeWidgetItem* Item1, QTreeWidgetItem* Item2)
|
|
{
|
|
QTreeWidgetItem* StepItem1 = Item1->parent();
|
|
QTreeWidgetItem* StepItem2 = Item2->parent();
|
|
|
|
if (StepItem1 == StepItem2)
|
|
return StepItem1->indexOfChild(Item1) < StepItem1->indexOfChild(Item2);
|
|
|
|
return indexOfTopLevelItem(StepItem1) < indexOfTopLevelItem(StepItem2);
|
|
};
|
|
|
|
std::sort(SelectedItems.begin(), SelectedItems.end(), SortItems);
|
|
|
|
for (QTreeWidgetItem* SelectedItem : std::as_const(SelectedItems))
|
|
SelectedItem->setSelected(true);
|
|
|
|
QTreeWidget::dropEvent(Event);
|
|
|
|
UpdateModel();
|
|
Update(false, false);
|
|
}
|
|
|
|
void lcTimelineWidget::mousePressEvent(QMouseEvent* Event)
|
|
{
|
|
if (Event->button() == Qt::RightButton)
|
|
{
|
|
QItemSelection Selection = selectionModel()->selection();
|
|
|
|
bool Blocked = blockSignals(true);
|
|
QTreeWidget::mousePressEvent(Event);
|
|
blockSignals(Blocked);
|
|
|
|
selectionModel()->select(Selection, QItemSelectionModel::ClearAndSelect);
|
|
}
|
|
else
|
|
QTreeWidget::mousePressEvent(Event);
|
|
}
|
|
|
|
void lcTimelineWidget::mouseDoubleClickEvent(QMouseEvent* MouseEvent)
|
|
{
|
|
if (MouseEvent->button() == Qt::LeftButton)
|
|
{
|
|
QTreeWidgetItem* CurrentItem = currentItem();
|
|
PreviewSelection(CurrentItem);
|
|
}
|
|
|
|
QTreeWidget::mouseDoubleClickEvent(MouseEvent);
|
|
}
|
|
|
|
void lcTimelineWidget::PreviewSelection(QTreeWidgetItem* CurrentItem)
|
|
{
|
|
if (!CurrentItem)
|
|
return;
|
|
|
|
lcPiece* Piece = (lcPiece*)CurrentItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
|
|
if (!Piece)
|
|
return;
|
|
|
|
lcPieceData* PieceData = Piece->mPieceData.Get();
|
|
|
|
if (!PieceData)
|
|
return;
|
|
|
|
gMainWindow->PreviewPiece(PieceData, Piece->GetColorCode(), false);
|
|
}
|
|
|
|
void lcTimelineWidget::UpdateModel()
|
|
{
|
|
std::vector<std::pair<lcPiece*, lcStep>> PieceSteps;
|
|
|
|
for (int TopLevelItemIdx = 0; TopLevelItemIdx < topLevelItemCount(); TopLevelItemIdx++)
|
|
{
|
|
QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx);
|
|
|
|
for (int PieceItemIdx = 0; PieceItemIdx < StepItem->childCount(); PieceItemIdx++)
|
|
{
|
|
QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIdx);
|
|
lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value<uintptr_t>();
|
|
|
|
PieceSteps.emplace_back(std::pair<lcPiece*, lcStep>(Piece, TopLevelItemIdx + 1));
|
|
}
|
|
}
|
|
|
|
mIgnoreUpdates = true;
|
|
gMainWindow->GetActiveModel()->SetPieceSteps(PieceSteps);
|
|
mIgnoreUpdates = false;
|
|
}
|