! \internal This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref setSelectionRectMode is set to \ref QCP::srmSelect. First, it determines which axis rect was the origin of the selection rect judging by the starting point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be precise) associated with that axi
| 15297 | \see processRectZoom |
| 15298 | */ |
| 15299 | void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) |
| 15300 | { |
| 15301 | bool selectionStateChanged = false; |
| 15302 | |
| 15303 | if (mInteractions.testFlag(QCP::iSelectPlottables)) |
| 15304 | { |
| 15305 | QMap<int, QPair<QCPAbstractPlottable*, QCPDataSelection> > potentialSelections; // map key is number of selected data points, so we have selections sorted by size |
| 15306 | QRectF rectF(rect.normalized()); |
| 15307 | if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) |
| 15308 | { |
| 15309 | // determine plottables that were hit by the rect and thus are candidates for selection: |
| 15310 | foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) |
| 15311 | { |
| 15312 | if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) |
| 15313 | { |
| 15314 | QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); |
| 15315 | if (!dataSel.isEmpty()) |
| 15316 | potentialSelections.insertMulti(dataSel.dataPointCount(), QPair<QCPAbstractPlottable*, QCPDataSelection>(plottable, dataSel)); |
| 15317 | } |
| 15318 | } |
| 15319 | |
| 15320 | if (!mInteractions.testFlag(QCP::iMultiSelect)) |
| 15321 | { |
| 15322 | // only leave plottable with most selected points in map, since we will only select a single plottable: |
| 15323 | if (!potentialSelections.isEmpty()) |
| 15324 | { |
| 15325 | QMap<int, QPair<QCPAbstractPlottable*, QCPDataSelection> >::iterator it = potentialSelections.begin(); |
| 15326 | while (it != potentialSelections.end()-1) // erase all except last element |
| 15327 | it = potentialSelections.erase(it); |
| 15328 | } |
| 15329 | } |
| 15330 | |
| 15331 | bool additive = event->modifiers().testFlag(mMultiSelectModifier); |
| 15332 | // deselect all other layerables if not additive selection: |
| 15333 | if (!additive) |
| 15334 | { |
| 15335 | // emit deselection except to those plottables who will be selected afterwards: |
| 15336 | foreach (QCPLayer *layer, mLayers) |
| 15337 | { |
| 15338 | foreach (QCPLayerable *layerable, layer->children()) |
| 15339 | { |
| 15340 | if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) |
| 15341 | { |
| 15342 | bool selChanged = false; |
| 15343 | layerable->deselectEvent(&selChanged); |
| 15344 | selectionStateChanged |= selChanged; |
| 15345 | } |
| 15346 | } |
| 15347 | } |
| 15348 | } |
| 15349 | |
| 15350 | // go through selections in reverse (largest selection first) and emit select events: |
| 15351 | QMap<int, QPair<QCPAbstractPlottable*, QCPDataSelection> >::const_iterator it = potentialSelections.constEnd(); |
| 15352 | while (it != potentialSelections.constBegin()) |
| 15353 | { |
| 15354 | --it; |
| 15355 | if (mInteractions.testFlag(it.value().first->selectionCategory())) |
| 15356 | { |
nothing calls this directly
no test coverage detected