! called on selections changes. Propagates the selection/deselection of columns to the \c Spreadsheet object. */
| 3678 | called on selections changes. Propagates the selection/deselection of columns to the \c Spreadsheet object. |
| 3679 | */ |
| 3680 | void SpreadsheetView::selectionChanged(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/) { |
| 3681 | if (m_suppressSelectionChangedEvent) |
| 3682 | return; |
| 3683 | |
| 3684 | PERFTRACE(QLatin1String(Q_FUNC_INFO)); |
| 3685 | |
| 3686 | // reset the column that was previosly selected from the context menu, if any |
| 3687 | m_selectedColumnFromContextMenu = -1; |
| 3688 | |
| 3689 | // determine the columns that were fully selected or deselected in the spreadsheet to also select/deselect them in the project explorer |
| 3690 | const auto* selModel = m_tableView->selectionModel(); |
| 3691 | int fullySelectedCount = 0; // the number of fully selected columns |
| 3692 | bool notFullySelected = false; // check if we have columns that are not fully selected (some cells selected only) |
| 3693 | for (int col = 0; col < m_spreadsheet->columnCount(); ++col) { |
| 3694 | const bool selected = selModel->isColumnSelected(col); |
| 3695 | m_spreadsheet->setColumnSelectedInView(col, selected); |
| 3696 | if (selected) |
| 3697 | ++fullySelectedCount; |
| 3698 | else if (!notFullySelected) // |
| 3699 | notFullySelected = selModel->columnIntersectsSelection(col); |
| 3700 | } |
| 3701 | |
| 3702 | // determine the number of selected cells, columns, missing and masked values in the current selection and show this information in the status bar. |
| 3703 | // Note, calling selModel->selectedIndexes() is very expensive for a high number of rows/cells in the spreadsheet and when whole columns are being |
| 3704 | // selected by clicking on the spreadsheet header. To avoid calling this expensive functions, handle the case when only full columns were selected: |
| 3705 | if (fullySelectedCount > 0 && !notFullySelected && m_spreadsheet->rowCount() > 10000) { |
| 3706 | Q_EMIT m_spreadsheet->statusInfo(i18n("Selected 1: %1 rows, %2 columns", m_spreadsheet->rowCount(), fullySelectedCount)); |
| 3707 | return; |
| 3708 | } |
| 3709 | |
| 3710 | const auto& indexes = selModel->selectedIndexes(); |
| 3711 | if (indexes.empty() || indexes.count() == 1) { |
| 3712 | Q_EMIT m_spreadsheet->statusInfo(QString()); |
| 3713 | return; |
| 3714 | } |
| 3715 | else if (indexes.count() > 10000) { // more than 10k selected cells, skip the expensive logic below to check for maskes values, etc. |
| 3716 | Q_EMIT m_spreadsheet->statusInfo(i18n("Selected: %1 cells", indexes.count())); |
| 3717 | return; |
| 3718 | } |
| 3719 | |
| 3720 | const auto& columns = m_spreadsheet->children<Column>(); |
| 3721 | int maskedValuesCount = 0; |
| 3722 | int missingValuesCount = 0; |
| 3723 | for (const auto& index : indexes) { |
| 3724 | const int col = index.column(); |
| 3725 | const int row = index.row(); |
| 3726 | const auto& column = columns.at(col); |
| 3727 | if (!column->isValid(row)) |
| 3728 | missingValuesCount++; |
| 3729 | if (column->isMasked(row)) |
| 3730 | maskedValuesCount++; |
| 3731 | } |
| 3732 | |
| 3733 | const int selectedCellsCount = indexes.count(); |
| 3734 | const QPair<int, int> selectedRowCol = qMakePair(selectedRowCount(false), selectedColumnCount(false)); |
| 3735 | QString selectedRowsText = i18np("row", "rows", selectedRowCol.first); |
| 3736 | QString selectedColumnsText = i18np("column", "columns", selectedRowCol.second); |
| 3737 | QString selectedCellsText = i18n("cells"); |
nothing calls this directly
no test coverage detected