| 345 | } |
| 346 | |
| 347 | void DocumentView::updateCache( Int64 fromLine, Int64 toLine, Int64 numLines ) { |
| 348 | if ( 0 == mMaxWidth || isOneToOne() || !mDoc ) |
| 349 | return; |
| 350 | |
| 351 | // Safety check: ensure fromLine and toLine are within bounds of the old state |
| 352 | if ( fromLine < 0 || fromLine >= (Int64)mVisibleLinesOffset.size() || |
| 353 | toLine < 0 || toLine >= (Int64)mVisibleLinesOffset.size() || fromLine > toLine ) { |
| 354 | invalidateCache(); |
| 355 | return; |
| 356 | } |
| 357 | |
| 358 | // Unfold ANY modification over a folded range |
| 359 | if ( numLines < 0 ) { |
| 360 | auto foldedRegions = intersectsFoldedRegions( { { fromLine, 0 }, { toLine, 0 } } ); |
| 361 | for ( const auto& fold : foldedRegions ) |
| 362 | unfoldRegion( fold.start().line(), false, false, false ); |
| 363 | } else if ( isFolded( fromLine ) ) { |
| 364 | // Offsets will be recomputed here instead in the unfold operation |
| 365 | unfoldRegion( fromLine, false, false, false ); |
| 366 | } |
| 367 | |
| 368 | // Get affected visible range |
| 369 | Int64 oldIdxFrom = static_cast<Int64>( toVisibleIndex( fromLine, false ) ); |
| 370 | Int64 oldIdxTo = static_cast<Int64>( toVisibleIndex( toLine, true ) ); |
| 371 | |
| 372 | if ( oldIdxFrom == static_cast<Int64>( VisibleIndex::invalid ) || |
| 373 | oldIdxTo == static_cast<Int64>( VisibleIndex::invalid ) || |
| 374 | oldIdxFrom > oldIdxTo || |
| 375 | oldIdxFrom >= (Int64)mVisibleLines.size() || |
| 376 | oldIdxTo >= (Int64)mVisibleLines.size() ) { |
| 377 | invalidateCache(); |
| 378 | return; |
| 379 | } |
| 380 | |
| 381 | auto visibleLinesCount = mVisibleLines.size(); |
| 382 | |
| 383 | // Remove old visible lines |
| 384 | mVisibleLines.erase( mVisibleLines.begin() + oldIdxFrom, mVisibleLines.begin() + oldIdxTo + 1 ); |
| 385 | |
| 386 | // Remove old offsets |
| 387 | mVisibleLinesOffset.erase( mVisibleLinesOffset.begin() + fromLine, |
| 388 | mVisibleLinesOffset.begin() + toLine + 1 ); |
| 389 | |
| 390 | // Shift the line numbers |
| 391 | if ( numLines != 0 ) { |
| 392 | visibleLinesCount = mVisibleLines.size(); |
| 393 | for ( Int64 i = oldIdxFrom; i < static_cast<Int64>( visibleLinesCount ); i++ ) |
| 394 | mVisibleLines[i].setLine( mVisibleLines[i].line() + numLines ); |
| 395 | |
| 396 | shiftFoldingRegions( fromLine, numLines ); |
| 397 | } |
| 398 | |
| 399 | // Recompute line breaks |
| 400 | auto netLines = toLine + numLines; |
| 401 | auto idxOffset = oldIdxFrom; |
| 402 | |
| 403 | if ( netLines >= (Int64)mDocLineToVisibleIndex.size() ) |
| 404 | mDocLineToVisibleIndex.resize( netLines + 1, static_cast<Int64>( VisibleIndex::invalid ) ); |