From b25d46bf9fa6d5b9ff34115edb4719592c191935 Mon Sep 17 00:00:00 2001 From: Dag Andersen Date: Tue, 23 Aug 2016 08:01:58 +0200 Subject: [PATCH 69/80] Backport: Plan: Avoid crash in special cases Sometimes (eg. when New is pressed) the Project can be deleted before models and thus cause a crash. Added a Project::aboutToBeDeleted signal so models can adjust. BUG: 346976 FIXED_IN: 2.9.12 --- plan/libs/kernel/kptproject.cpp | 1 + plan/libs/kernel/kptproject.h | 2 ++ plan/libs/models/kptaccountsmodel.cpp | 2 ++ plan/libs/models/kptcalendarmodel.cpp | 4 ++++ plan/libs/models/kptitemmodelbase.cpp | 5 +++++ plan/libs/models/kptitemmodelbase.h | 1 + plan/libs/models/kptnodechartmodel.cpp | 2 ++ plan/libs/models/kptnodeitemmodel.cpp | 4 ++++ plan/libs/models/kptpertcpmmodel.cpp | 4 ++++ plan/libs/models/kptrelationmodel.cpp | 2 ++ plan/libs/models/kptresourceallocationmodel.cpp | 2 ++ plan/libs/models/kptresourceappointmentsmodel.cpp | 8 ++++++++ plan/libs/models/kptresourcemodel.cpp | 12 +++++++----- plan/libs/models/kptschedulemodel.cpp | 13 +++++++++++++ plan/libs/models/kptschedulemodel.h | 2 ++ plan/libs/models/kpttaskstatusmodel.cpp | 2 ++ 16 files changed, 61 insertions(+), 5 deletions(-) diff --git a/plan/libs/kernel/kptproject.cpp b/plan/libs/kernel/kptproject.cpp index 158040b..451e897 100644 --- a/plan/libs/kernel/kptproject.cpp +++ b/plan/libs/kernel/kptproject.cpp @@ -89,6 +89,7 @@ void Project::deref() --m_refCount; Q_ASSERT( m_refCount >= 0 ); if ( m_refCount <= 0 ) { + emit aboutToBeDeleted(); deleteLater(); } } diff --git a/plan/libs/kernel/kptproject.h b/plan/libs/kernel/kptproject.h index 1dbea7d..db18d36 100644 --- a/plan/libs/kernel/kptproject.h +++ b/plan/libs/kernel/kptproject.h @@ -519,6 +519,8 @@ public Q_SLOTS: void setMaxProgress( int max, ScheduleManager *sm = 0 ); Q_SIGNALS: + /// Emitted when the project is about to be deleted (The destroyed signal is disabled) + void aboutToBeDeleted(); /// Emitted when anything in the project is changed (use with care) void projectChanged(); /// Emitted when the WBS code definition has changed. This may change all nodes. diff --git a/plan/libs/models/kptaccountsmodel.cpp b/plan/libs/models/kptaccountsmodel.cpp index 53f725a..4657979 100644 --- a/plan/libs/models/kptaccountsmodel.cpp +++ b/plan/libs/models/kptaccountsmodel.cpp @@ -533,6 +533,7 @@ void CostBreakdownItemModel::setProject( Project *project ) disconnect( acc, SIGNAL(accountRemoved(const Account*)), this, SLOT(slotAccountRemoved(const Account*)) ); disconnect( acc, SIGNAL(accountToBeRemoved(const Account*)), this, SLOT(slotAccountToBeRemoved(const Account*)) ); + disconnect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); disconnect( m_project , SIGNAL(nodeChanged(Node*)), this, SLOT(slotDataChanged()) ); disconnect( m_project , SIGNAL(nodeAdded(Node*)), this, SLOT(slotDataChanged()) ); disconnect( m_project , SIGNAL(nodeRemoved(Node*)), this, SLOT(slotDataChanged()) ); @@ -553,6 +554,7 @@ void CostBreakdownItemModel::setProject( Project *project ) connect( acc, SIGNAL(accountRemoved(const Account*)), this, SLOT(slotAccountRemoved(const Account*)) ); connect( acc, SIGNAL(accountToBeRemoved(const Account*)), this, SLOT(slotAccountToBeRemoved(const Account*)) ); + connect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); connect( m_project , SIGNAL(nodeChanged(Node*)), this, SLOT(slotDataChanged()) ); connect( m_project , SIGNAL(nodeAdded(Node*)), this, SLOT(slotDataChanged()) ); connect( m_project , SIGNAL(nodeRemoved(Node*)), this, SLOT(slotDataChanged()) ); diff --git a/plan/libs/models/kptcalendarmodel.cpp b/plan/libs/models/kptcalendarmodel.cpp index 6c0f017..401379c 100644 --- a/plan/libs/models/kptcalendarmodel.cpp +++ b/plan/libs/models/kptcalendarmodel.cpp @@ -74,10 +74,12 @@ void CalendarDayItemModelBase::setProject( Project *project ) { setCalendar( 0 ); if ( m_project ) { + disconnect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); disconnect( m_project, SIGNAL(calendarToBeRemoved(const Calendar*)), this, SLOT(slotCalendarToBeRemoved(const Calendar*)) ); } m_project = project; if ( project ) { + connect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); connect( m_project, SIGNAL(calendarToBeRemoved(const Calendar*)), this, SLOT(slotCalendarToBeRemoved(const Calendar*)) ); } reset(); @@ -136,6 +138,7 @@ void CalendarItemModel::slotCalendarRemoved( const Calendar * ) void CalendarItemModel::setProject( Project *project ) { if ( m_project ) { + disconnect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); disconnect( m_project , SIGNAL(calendarChanged(Calendar*)), this, SLOT(slotCalendarChanged(Calendar*)) ); disconnect( m_project, SIGNAL(calendarAdded(const Calendar*)), this, SLOT(slotCalendarInserted(const Calendar*)) ); @@ -146,6 +149,7 @@ void CalendarItemModel::setProject( Project *project ) } m_project = project; if ( project ) { + connect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); connect( m_project, SIGNAL(calendarChanged(Calendar*)), this, SLOT(slotCalendarChanged(Calendar*)) ); connect( m_project, SIGNAL(calendarAdded(const Calendar*)), this, SLOT(slotCalendarInserted(const Calendar*)) ); diff --git a/plan/libs/models/kptitemmodelbase.cpp b/plan/libs/models/kptitemmodelbase.cpp index 499fcfe..ff74394 100644 --- a/plan/libs/models/kptitemmodelbase.cpp +++ b/plan/libs/models/kptitemmodelbase.cpp @@ -731,6 +731,11 @@ bool ItemModelBase::setData( const QModelIndex &index, const QVariant &value, in return false; } +void ItemModelBase::projectDeleted() +{ + setProject(0); +} + } //namespace KPlato #include "kptitemmodelbase.moc" diff --git a/plan/libs/models/kptitemmodelbase.h b/plan/libs/models/kptitemmodelbase.h index 578c18e..5d3719d 100644 --- a/plan/libs/models/kptitemmodelbase.h +++ b/plan/libs/models/kptitemmodelbase.h @@ -309,6 +309,7 @@ protected Q_SLOTS: virtual void slotLayoutToBeChanged(); virtual void slotLayoutChanged(); + void projectDeleted(); protected: Project *m_project; ScheduleManager *m_manager; diff --git a/plan/libs/models/kptnodechartmodel.cpp b/plan/libs/models/kptnodechartmodel.cpp index 025da86..9b8d397 100644 --- a/plan/libs/models/kptnodechartmodel.cpp +++ b/plan/libs/models/kptnodechartmodel.cpp @@ -294,6 +294,7 @@ void ChartItemModel::setProject( Project *project ) m_bcws.clear(); m_acwp.clear(); if ( m_project ) { + disconnect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); disconnect( m_project, SIGNAL(projectCalculated(ScheduleManager*)), this, SLOT(setScheduleManager(ScheduleManager*)) ); disconnect( m_project, SIGNAL(nodeRemoved(Node*)), this, SLOT(slotNodeRemoved(Node*)) ); disconnect( m_project, SIGNAL(nodeChanged(Node*)), this, SLOT(slotNodeChanged(Node*)) ); @@ -302,6 +303,7 @@ void ChartItemModel::setProject( Project *project ) } m_project = project; if ( m_project ) { + connect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); connect( m_project, SIGNAL(projectCalculated(ScheduleManager*)), this, SLOT(setScheduleManager(ScheduleManager*)) ); connect( m_project, SIGNAL(nodeRemoved(Node*)), this, SLOT(slotNodeRemoved(Node*)) ); connect( m_project, SIGNAL(nodeChanged(Node*)), this, SLOT(slotNodeChanged(Node*)) ); diff --git a/plan/libs/models/kptnodeitemmodel.cpp b/plan/libs/models/kptnodeitemmodel.cpp index 45b1650..e66277f 100644 --- a/plan/libs/models/kptnodeitemmodel.cpp +++ b/plan/libs/models/kptnodeitemmodel.cpp @@ -3122,6 +3122,7 @@ void NodeItemModel::slotWbsDefinitionChanged() void NodeItemModel::setProject( Project *project ) { if ( m_project ) { + disconnect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); disconnect( m_project, SIGNAL(localeChanged()), this, SLOT(slotLayoutChanged()) ); disconnect( m_project, SIGNAL(wbsDefinitionChanged()), this, SLOT(slotWbsDefinitionChanged()) ); disconnect( m_project, SIGNAL(nodeChanged(Node*)), this, SLOT(slotNodeChanged(Node*)) ); @@ -3139,6 +3140,7 @@ void NodeItemModel::setProject( Project *project ) kDebug(planDbg())<"<"<( object( index ) ); + Resource *r = resource( index ); if ( r && r->parentGroup() ) { // only resources have parent int row = m_project->indexOf( r->parentGroup() ); @@ -732,8 +734,7 @@ QModelIndex ResourceItemModel::index( int row, int column, const QModelIndex &pa } return QModelIndex(); } - QObject *p = object( parent ); - ResourceGroup *g = qobject_cast( p ); + ResourceGroup *g = group( parent ); if ( g ) { if ( row < g->numResources() ) { return createIndex( row, column, g->resourceAt( row ) ); @@ -782,8 +783,7 @@ int ResourceItemModel::rowCount( const QModelIndex &parent ) const if ( ! parent.isValid() ) { return m_project->numResourceGroups(); } - QObject *p = object( parent ); - ResourceGroup *g = qobject_cast( p ); + ResourceGroup *g = group( parent ); if ( g ) { return g->numResources(); } @@ -1148,6 +1148,8 @@ QObject *ResourceItemModel::object( const QModelIndex &index ) const { QObject *o = 0; if ( index.isValid() ) { + Q_ASSERT( m_project ); + Q_ASSERT(m_project->resourceGroups().contains(static_cast(index.internalPointer())) || m_project->resourceList().contains(static_cast(index.internalPointer()))); o = static_cast( index.internalPointer() ); Q_ASSERT( o ); } diff --git a/plan/libs/models/kptschedulemodel.cpp b/plan/libs/models/kptschedulemodel.cpp index e3ce298..4d47ee5 100644 --- a/plan/libs/models/kptschedulemodel.cpp +++ b/plan/libs/models/kptschedulemodel.cpp @@ -171,6 +171,8 @@ void ScheduleItemModel::slotScheduleRemoved( const MainSchedule * ) void ScheduleItemModel::setProject( Project *project ) { if ( m_project ) { + disconnect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); + disconnect( m_project, SIGNAL(scheduleManagerChanged(ScheduleManager*)), this, SLOT(slotManagerChanged(ScheduleManager*)) ); disconnect( m_project, SIGNAL(scheduleManagerToBeAdded(const ScheduleManager*,int)), this, SLOT(slotScheduleManagerToBeInserted(const ScheduleManager*,int)) ); @@ -197,6 +199,8 @@ void ScheduleItemModel::setProject( Project *project ) } m_project = project; if ( m_project ) { + connect(m_project, SIGNAL(aboutToBeDeleted()), this, SLOT(projectDeleted())); + connect( m_project, SIGNAL(scheduleManagerChanged(ScheduleManager*)), this, SLOT(slotManagerChanged(ScheduleManager*)) ); connect( m_project, SIGNAL(scheduleManagerToBeAdded(const ScheduleManager*,int)), this, SLOT(slotScheduleManagerToBeInserted(const ScheduleManager*,int)) ); @@ -1074,10 +1078,17 @@ void ScheduleLogItemModel::slotScheduleRemoved( const MainSchedule *sch ) kDebug(planDbg())<"<