insertRowGroup method

  1. @override
  2. @protected
void insertRowGroup(
  1. int index,
  2. List<PlutoRow> rows
)
inherited

Implementation

@override
@protected
void insertRowGroup(int index, List<PlutoRow> rows) {
  if (rows.isEmpty) {
    return;
  }

  assert(enabledRowGroups);

  if (!rows.first.initialized) {
    PlutoGridStateManager.initializeRows(
      refColumns.originalList,
      rows,
      forceApplySortIdx: false,
    );
  }

  final bool append = index >= refRows.length;
  final targetIdx = append ? refRows.length - 1 : index;
  final target = refRows.isEmpty ? null : refRows[targetIdx];

  if (rowGroupDelegate is PlutoRowGroupByColumnDelegate && !append) {
    _updateCellsByTargetForGroupByColumn(rows: rows, target: target);
  }

  final grouped = rowGroupDelegate!.toGroup(rows: rows);

  bool findByTargetKey(PlutoRow e) => e.key == target?.key;

  bool hasChildrenGroup(PlutoRow found) {
    return found.type.isGroup &&
        found.type.group.children.originalList.isNotEmpty &&
        found.type.group.children.originalList.first.type.isGroup;
  }

  void updateSortIdx({
    required List<PlutoRow> rows,
    required int start,
    required int compare,
    required int increase,
  }) {
    if (hasSortedColumn) {
      for (final row in rows) {
        if (compare >= row.sortIdx) {
          row.sortIdx += increase;
        }
      }
    } else {
      final length = rows.length;
      for (int i = start; i < length; i += 1) {
        rows[i].sortIdx += increase;
      }
    }
  }

  void updateAddedRow(PlutoRow row) {
    row.setState(PlutoRowState.added);
    if (row.type.isGroup) {
      updateChild(PlutoRow e) {
        e.setParent(row);
        updateAddedRow(e);
      }

      row.type.group.children.originalList.forEach(updateChild);
    }
  }

  void updateAddedChildren(PlutoRow parent, List<PlutoRow> children) {
    parent.setState(PlutoRowState.updated);
    updateChild(PlutoRow e) {
      e.setParent(parent);
      updateAddedRow(e);
    }

    children.forEach(updateChild);
  }

  void insertOrAdd({
    required FilteredList<PlutoRow> ref,
    required PlutoRow row,
    PlutoRow? parent,
  }) {
    row.setParent(parent);
    updateAddedRow(row);

    final insertIdx = ref.indexWhere(findByTargetKey);
    if (insertIdx > -1 && !append) {
      row.sortIdx = ref[insertIdx].sortIdx;
      updateSortIdx(
        rows: ref,
        start: insertIdx,
        compare: row.sortIdx,
        increase: 1,
      );
      ref.insert(insertIdx, row);
    } else {
      ref.add(row);
    }
  }

  void insertOrAddToChildren({
    required PlutoRow found,
    required PlutoRow row,
  }) {
    assert(row.type.isGroup);
    updateAddedChildren(found, row.type.group.children.originalList);

    final insertIdx = found.type.group.children.indexWhere(findByTargetKey);
    if (insertIdx > -1 && !append) {
      final length = row.type.group.children.length;
      for (int i = 0; i < length; i += 1) {
        row.type.group.children[i].sortIdx =
            found.type.group.children[insertIdx].sortIdx + i;
      }
      updateSortIdx(
        rows: found.type.group.children,
        start: insertIdx,
        compare: found.type.group.children[insertIdx].sortIdx,
        increase: row.type.group.children.length,
      );
      found.type.group.children.insertAll(
        insertIdx,
        row.type.group.children,
      );
    } else {
      found.type.group.children.addAll(row.type.group.children);
    }
  }

  void addAllGroupByColumn(
    Iterable<PlutoRow> groupedRows,
    FilteredList<PlutoRow> ref,
    PlutoRow? parent,
  ) {
    for (final row in groupedRows) {
      findByRowKey(PlutoRow e) => e.key == row.key;
      final found = ref.originalList.firstWhereOrNull(findByRowKey);

      if (found == null) {
        insertOrAdd(ref: ref, row: row, parent: parent);
      } else {
        if (hasChildrenGroup(found)) {
          addAllGroupByColumn(
            row.type.group.children,
            found.type.group.children,
            found,
          );
        } else {
          insertOrAddToChildren(found: found, row: row);
        }
      }
    }
  }

  void addAllGroupTree() {
    final targetParent = target?.parent?.type.group.children ?? refRows;

    if (target?.parent == null) {
      grouped.forEach(updateAddedRow);
    } else {
      updateAddedChildren(target!.parent!, grouped);
    }

    if (append) {
      targetParent.addAll(grouped);
      return;
    }

    final targetParentList = targetParent.filterOrOriginalList;
    final insertIdx = targetParentList.indexWhere(findByTargetKey);
    assert(insertIdx != -1);

    final length = grouped.length;
    for (int i = 0; i < length; i += 1) {
      grouped[i].sortIdx = (target?.sortIdx ?? 0) + i;
    }

    updateSortIdx(
      rows: targetParent.originalList,
      start: target == null ? 0 : targetParent.originalList.indexOf(target),
      compare: target?.sortIdx ?? 0,
      increase: grouped.length,
    );

    targetParent.insertAll(insertIdx, grouped);
  }

  _ensureRowGroups(() {
    switch (rowGroupDelegate!.type) {
      case PlutoRowGroupDelegateType.tree:
        addAllGroupTree();
        break;
      case PlutoRowGroupDelegateType.byColumn:
        addAllGroupByColumn(grouped, refRows, null);
        break;
    }
  });

  refRows.update();
}