From c4b15d05a95410fa635c3ad41fcea24c9290fa26 Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 14 Mar 2015 19:07:07 +0000 Subject: [PATCH] Fixed timeline update crash. --- common/lc_application.cpp | 3 +- common/lc_mainwindow.cpp | 2 - common/lc_model.cpp | 86 ++++++++++++++++++--------- common/lc_model.h | 2 + common/lc_timelinewidget.cpp | 109 ++++++++++++++++++++++++++--------- qt/qtmain.cpp | 1 - 6 files changed, 144 insertions(+), 59 deletions(-) diff --git a/common/lc_application.cpp b/common/lc_application.cpp index f3c3aa2e..f7eac8fb 100644 --- a/common/lc_application.cpp +++ b/common/lc_application.cpp @@ -72,9 +72,8 @@ void lcApplication::SetProject(Project* Project) View->SetModel(lcGetActiveModel()); } + Project->SetActiveModel(0); lcGetPiecesLibrary()->RemoveTemporaryPieces(); - lcGetActiveModel()->UpdateInterface(); - gMainWindow->UpdateAllViews(); } void lcApplication::SetClipboard(const QByteArray& Clipboard) diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 139277cf..1c782d54 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -1658,8 +1658,6 @@ bool lcMainWindow::OpenProject(const QString& FileName) if (NewProject->Load(LoadFileName)) { - NewProject->SetActiveModel(0); - g_App->SetProject(NewProject); AddRecentFile(LoadFileName); diff --git a/common/lc_model.cpp b/common/lc_model.cpp index d2a2b82c..6569165a 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -510,7 +510,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project) Piece->SetPieceInfo(Info); Piece->Initialize(Transform, CurrentStep); Piece->SetColorCode(ColorCode); - mPieces.Add(Piece); + AddPiece(Piece); Piece = NULL; } } @@ -587,7 +587,7 @@ bool lcModel::LoadBinary(lcFile* file) { lcPiece* pPiece = new lcPiece(NULL); pPiece->FileLoad(*file); - mPieces.Add(pPiece); + AddPiece(pPiece); } else { @@ -611,7 +611,7 @@ bool lcModel::LoadBinary(lcFile* file) pPiece->Initialize(WorldMatrix, step); pPiece->SetColorCode(lcGetColorCodeFromOriginalColor(color)); - mPieces.Add(pPiece); + AddPiece(pPiece); // pPiece->SetGroup((lcGroup*)group); } @@ -816,7 +816,7 @@ void lcModel::Merge(lcModel* Other) for (int PieceIdx = 0; PieceIdx < Other->mPieces.GetSize(); PieceIdx++) { lcPiece* Piece = Other->mPieces[PieceIdx]; - mPieces.Add(Piece); + AddPiece(Piece); } Other->mPieces.RemoveAll(); @@ -1834,12 +1834,26 @@ void lcModel::AddPiece() lcPiece* Piece = new lcPiece(CurPiece); Piece->Initialize(WorldMatrix, mCurrentStep); Piece->SetColorIndex(gMainWindow->mColorIndex); - mPieces.Add(Piece); + AddPiece(Piece); ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION); SaveCheckpoint("Adding Piece"); } +void lcModel::AddPiece(lcPiece* Piece) +{ + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + if (mPieces[PieceIdx]->GetStepShow() > Piece->GetStepShow()) + { + mPieces.InsertAt(PieceIdx, Piece); + return; + } + } + + mPieces.Add(Piece); +} + void lcModel::DeleteAllCameras() { if (mCameras.IsEmpty()) @@ -1866,9 +1880,9 @@ void lcModel::DeleteSelectedObjects() void lcModel::ShowSelectedPiecesEarlier() { - bool Modified = false; + lcArray MovedPieces; - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; @@ -1879,25 +1893,34 @@ void lcModel::ShowSelectedPiecesEarlier() if (Step > 1) { Step--; - Modified = true; Piece->SetStepShow(Step); + + MovedPieces.Add(Piece); + mPieces.RemoveIndex(PieceIdx); + continue; } } + + PieceIdx++; } - if (Modified) - { - SaveCheckpoint("Modifying"); - gMainWindow->UpdateAllViews(); - UpdateSelection(); - } + if (MovedPieces.IsEmpty()) + return; + + for (int PieceIdx = 0; PieceIdx < MovedPieces.GetSize(); PieceIdx++) + AddPiece(MovedPieces[PieceIdx]); + + SaveCheckpoint("Modifying"); + gMainWindow->UpdateAllViews(); + gMainWindow->UpdateTimeline(); + UpdateSelection(); } void lcModel::ShowSelectedPiecesLater() { - bool Modified = false; + lcArray MovedPieces; - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; @@ -1908,22 +1931,30 @@ void lcModel::ShowSelectedPiecesLater() if (Step < LC_STEP_MAX) { Step++; - Modified = true; Piece->SetStepShow(Step); if (Step > mCurrentStep) Piece->SetSelected(false); + + MovedPieces.Add(Piece); + mPieces.RemoveIndex(PieceIdx); + continue; } } + + PieceIdx++; } - if (Modified) - { - SaveCheckpoint("Modifying"); - gMainWindow->UpdateAllViews(); - UpdateSelection(); - gMainWindow->UpdateFocusObject(GetFocusObject()); - } + if (MovedPieces.IsEmpty()) + return; + + for (int PieceIdx = 0; PieceIdx < MovedPieces.GetSize(); PieceIdx++) + AddPiece(MovedPieces[PieceIdx]); + + SaveCheckpoint("Modifying"); + gMainWindow->UpdateAllViews(); + gMainWindow->UpdateTimeline(); + UpdateSelection(); } void lcModel::SetPieceSteps(const QList>& PieceSteps) @@ -3153,7 +3184,7 @@ void lcModel::InsertPieceToolClicked(const lcMatrix44& WorldMatrix) Piece->Initialize(WorldMatrix, mCurrentStep); Piece->SetColorIndex(gMainWindow->mColorIndex); Piece->UpdatePosition(mCurrentStep); - mPieces.Add(Piece); + AddPiece(Piece); ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION); @@ -3515,7 +3546,7 @@ void lcModel::ShowArrayDialog() { lcPiece* Piece = (lcPiece*)NewPieces[PieceIdx]; Piece->UpdatePosition(mCurrentStep); - mPieces.Add(Piece); + AddPiece(Piece); } AddToSelection(NewPieces); @@ -3544,7 +3575,7 @@ void lcModel::ShowMinifigDialog() Piece->Initialize(Minifig.Matrices[PartIdx], mCurrentStep); Piece->SetColorIndex(Minifig.Colors[PartIdx]); Piece->SetGroup(Group); - mPieces.Add(Piece); + AddPiece(Piece); Piece->UpdatePosition(mCurrentStep); Pieces.Add(Piece); @@ -3556,6 +3587,7 @@ void lcModel::ShowMinifigDialog() void lcModel::UpdateInterface() { + gMainWindow->UpdateTimeline(); gMainWindow->UpdateUndoRedo(mUndoHistory.GetSize() > 1 ? mUndoHistory[0]->Description : NULL, !mRedoHistory.IsEmpty() ? mRedoHistory[0]->Description : NULL); gMainWindow->UpdatePaste(!g_App->mClipboard.isEmpty()); gMainWindow->UpdateCategories(); diff --git a/common/lc_model.h b/common/lc_model.h index cab84931..d41956c1 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -327,6 +327,8 @@ protected: void UpdateSelection() const; void SelectGroup(lcGroup* TopGroup, bool Select); + void AddPiece(lcPiece* Piece); + lcModelProperties mProperties; PieceInfo* mPieceInfo; diff --git a/common/lc_timelinewidget.cpp b/common/lc_timelinewidget.cpp index 8ecbf167..7af90d2c 100644 --- a/common/lc_timelinewidget.cpp +++ b/common/lc_timelinewidget.cpp @@ -26,21 +26,16 @@ lcTimelineWidget::~lcTimelineWidget() { } -void lcTimelineWidget::CustomMenuRequested(QPoint Pos) -{ - QList SelectedItems = selectedItems(); - - if (!SelectedItems.isEmpty()) - { - QMenu* Menu = new QMenu(this); +void lcTimelineWidget::CustomMenuRequested(QPoint Pos) +{ + QMenu* Menu = new QMenu(this); - Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_SELECTED]); - Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_UNSELECTED]); - Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_ALL]); - - Menu->popup(viewport()->mapToGlobal(Pos)); - } -} + Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_SELECTED]); + Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_UNSELECTED]); + Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_ALL]); + + Menu->popup(viewport()->mapToGlobal(Pos)); +} void lcTimelineWidget::Update() { @@ -57,8 +52,20 @@ void lcTimelineWidget::Update() int Steps = Model->GetLastStep(); - for (int TopLevelItemIdx = Steps; TopLevelItemIdx < topLevelItemCount(); TopLevelItemIdx++) - delete topLevelItem(TopLevelItemIdx); + for (int TopLevelItemIdx = Steps; TopLevelItemIdx < topLevelItemCount(); ) + { + QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx); + + while (StepItem->childCount()) + { + QTreeWidgetItem* PieceItem = StepItem->child(0); + lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); + mItems.remove(Piece); + delete PieceItem; + } + + delete StepItem; + } for (int Step = topLevelItemCount(); Step < Steps; Step++) { @@ -69,28 +76,76 @@ void lcTimelineWidget::Update() } const lcArray& Pieces = Model->GetPieces(); + QTreeWidgetItem* StepItem = NULL; + int PieceItemIndex = 0; + int Step = -1; - for (int PieceIdx = 0; PieceIdx < Pieces.GetSize(); PieceIdx++) + for (int PieceIdx = 0; PieceIdx != Pieces.GetSize(); PieceIdx++) { lcPiece* Piece = Pieces[PieceIdx]; - QTreeWidgetItem* PieceItem = mItems.value(Piece); - QTreeWidgetItem* StepItem = topLevelItem(Piece->GetStepShow() - 1); - if (PieceItem) + if (Step != Piece->GetStepShow()) { - if (PieceItem->parent() != StepItem) - StepItem->addChild(PieceItem); + if (StepItem) + { + while (PieceItemIndex < StepItem->childCount()) + { + QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex); + lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); + + if (Pieces.FindIndex(RemovePiece) == -1) + { + mItems.remove(RemovePiece); + delete PieceItem; + } + else + { + PieceItem->parent()->removeChild(PieceItem); + topLevelItem(RemovePiece->GetStepShow() - 1)->addChild(PieceItem); + } + } + } + + Step = Piece->GetStepShow(); + StepItem = topLevelItem(Step - 1); + PieceItemIndex = 0; + } + + QTreeWidgetItem* PieceItem = mItems.value(Piece); + + if (!PieceItem) + { + PieceItem = new QTreeWidgetItem(QStringList(Piece->mPieceInfo->m_strDescription)); + PieceItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); + PieceItem->setData(0, Qt::UserRole, qVariantFromValue((uintptr_t)Piece)); + StepItem->insertChild(PieceItemIndex, PieceItem); + mItems[Piece] = PieceItem; } else { - PieceItem = new QTreeWidgetItem(StepItem, QStringList(Piece->mPieceInfo->m_strDescription)); - PieceItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); - PieceItem->setData(0, Qt::UserRole, qVariantFromValue((uintptr_t)Piece)); - StepItem->addChild(PieceItem); - mItems[Piece] = PieceItem; + if (PieceItemIndex >= StepItem->childCount() || PieceItem != StepItem->child(PieceItemIndex)) + { + if (PieceItem->parent() == StepItem) + StepItem->removeChild(PieceItem); + + StepItem->insertChild(PieceItemIndex, PieceItem); + } } PieceItem->setSelected(Piece->IsSelected()); + PieceItemIndex++; + } + + if (!StepItem) + StepItem = topLevelItem(0); + + while (PieceItemIndex < StepItem->childCount()) + { + QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex); + lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); + + mItems.remove(RemovePiece); + delete PieceItem; } blockSignals(Blocked); diff --git a/qt/qtmain.cpp b/qt/qtmain.cpp index d203a317..5ad6aaa7 100644 --- a/qt/qtmain.cpp +++ b/qt/qtmain.cpp @@ -178,7 +178,6 @@ int main(int argc, char *argv[]) if (!g_App->Initialize(argc, argv, libPath, LDrawPath, cachePath.toLocal8Bit().data())) return 1; - lcGetActiveModel()->UpdateInterface(); gMainWindow->SetColorIndex(lcGetColorIndex(4)); gMainWindow->UpdateRecentFiles(); gMainWindow->show();