@ -80,6 +80,9 @@ public:
bool groupInline = false ;
bool groupInline = false ;
int groupingWindowTasksThreshold = - 1 ;
int groupingWindowTasksThreshold = - 1 ;
bool usedByQml = false ;
bool componentComplete = false ;
void initModels ( ) ;
void initModels ( ) ;
void initLauncherTasksModel ( ) ;
void initLauncherTasksModel ( ) ;
void updateAnyTaskDemandsAttention ( ) ;
void updateAnyTaskDemandsAttention ( ) ;
@ -438,17 +441,6 @@ void TasksModel::Private::initModels()
QObject : : connect ( groupingProxyModel , & QAbstractItemModel : : modelReset , q ,
QObject : : connect ( groupingProxyModel , & QAbstractItemModel : : modelReset , q ,
[ this ] ( ) { updateAnyTaskDemandsAttention ( ) ; }
[ this ] ( ) { updateAnyTaskDemandsAttention ( ) ; }
) ;
) ;
abstractTasksSourceModel = groupingProxyModel ;
q - > setSourceModel ( groupingProxyModel ) ;
QObject : : connect ( q , & QAbstractItemModel : : rowsInserted , q , & TasksModel : : updateLauncherCount ) ;
QObject : : connect ( q , & QAbstractItemModel : : rowsRemoved , q , & TasksModel : : updateLauncherCount ) ;
QObject : : connect ( q , & QAbstractItemModel : : modelReset , q , & TasksModel : : updateLauncherCount ) ;
QObject : : connect ( q , & QAbstractItemModel : : rowsInserted , q , & TasksModel : : countChanged ) ;
QObject : : connect ( q , & QAbstractItemModel : : rowsRemoved , q , & TasksModel : : countChanged ) ;
QObject : : connect ( q , & QAbstractItemModel : : modelReset , q , & TasksModel : : countChanged ) ;
}
}
void TasksModel : : Private : : updateAnyTaskDemandsAttention ( )
void TasksModel : : Private : : updateAnyTaskDemandsAttention ( )
@ -637,6 +629,12 @@ void TasksModel::Private::consolidateManualSortMapForGroup(const QModelIndex &gr
void TasksModel : : Private : : updateGroupInline ( )
void TasksModel : : Private : : updateGroupInline ( )
{
{
if ( usedByQml & & ! componentComplete ) {
return ;
}
bool hadSourceModel = ( q - > sourceModel ( ) ! = nullptr ) ;
if ( q - > groupMode ( ) ! = GroupDisabled & & groupInline ) {
if ( q - > groupMode ( ) ! = GroupDisabled & & groupInline ) {
if ( flattenGroupsProxyModel ) {
if ( flattenGroupsProxyModel ) {
return ;
return ;
@ -661,7 +659,7 @@ void TasksModel::Private::updateGroupInline()
forceResort ( ) ;
forceResort ( ) ;
}
}
} else {
} else {
if ( ! flattenGroupsProxyModel ) {
if ( hadSourceModel & & ! flattenGroupsProxyModel ) {
return ;
return ;
}
}
@ -674,10 +672,28 @@ void TasksModel::Private::updateGroupInline()
delete flattenGroupsProxyModel ;
delete flattenGroupsProxyModel ;
flattenGroupsProxyModel = nullptr ;
flattenGroupsProxyModel = nullptr ;
if ( sortMode = = SortManual ) {
if ( hadSourceModel & & sortMode = = SortManual ) {
forceResort ( ) ;
forceResort ( ) ;
}
}
}
}
// Minor optimization: We only make these connections after we populate for
// the first time to avoid some churn.
if ( ! hadSourceModel ) {
QObject : : connect ( q , & QAbstractItemModel : : rowsInserted , q ,
& TasksModel : : updateLauncherCount , Qt : : UniqueConnection ) ;
QObject : : connect ( q , & QAbstractItemModel : : rowsRemoved , q ,
& TasksModel : : updateLauncherCount , Qt : : UniqueConnection ) ;
QObject : : connect ( q , & QAbstractItemModel : : modelReset , q ,
& TasksModel : : updateLauncherCount , Qt : : UniqueConnection ) ;
QObject : : connect ( q , & QAbstractItemModel : : rowsInserted , q ,
& TasksModel : : countChanged , Qt : : UniqueConnection ) ;
QObject : : connect ( q , & QAbstractItemModel : : rowsRemoved , q ,
& TasksModel : : countChanged , Qt : : UniqueConnection ) ;
QObject : : connect ( q , & QAbstractItemModel : : modelReset , q ,
& TasksModel : : countChanged , Qt : : UniqueConnection ) ;
}
}
}
QModelIndex TasksModel : : Private : : preFilterIndex ( const QModelIndex & sourceIndex ) const {
QModelIndex TasksModel : : Private : : preFilterIndex ( const QModelIndex & sourceIndex ) const {
@ -893,6 +909,18 @@ TasksModel::TasksModel(QObject *parent)
// Start sorting.
// Start sorting.
sort ( 0 ) ;
sort ( 0 ) ;
// Private::updateGroupInline() sets our source model, populating the model. We
// delay running this until the QML runtime had a chance to call our implementation
// of QQmlParserStatus::classBegin(), setting Private::usedByQml to true. If used
// by QML, Private::updateGroupInline() will abort if the component is not yet
// complete, instead getting called through QQmlParserStatus::componentComplete()
// only after all properties have been set. This avoids delegate churn in Qt Quick
// views using the model. If not used by QML, Private::updateGroupInline() will run
// directly.
QTimer : : singleShot ( 0 , this , [ this ] ( ) {
d - > updateGroupInline ( ) ;
} ) ;
}
}
TasksModel : : ~ TasksModel ( )
TasksModel : : ~ TasksModel ( )
@ -1684,6 +1712,19 @@ QModelIndex TasksModel::makeModelIndex(int row, int childRow) const
return QModelIndex ( ) ;
return QModelIndex ( ) ;
}
}
void TasksModel : : classBegin ( )
{
d - > usedByQml = true ;
}
void TasksModel : : componentComplete ( )
{
d - > componentComplete = true ;
// Sets our source model, populating the model.
d - > updateGroupInline ( ) ;
}
bool TasksModel : : filterAcceptsRow ( int sourceRow , const QModelIndex & sourceParent ) const
bool TasksModel : : filterAcceptsRow ( int sourceRow , const QModelIndex & sourceParent ) const
{
{
// All our filtering occurs at the top-level; anything below always
// All our filtering occurs at the top-level; anything below always