https://bugs.kde.org/show_bug.cgi?id=362485
Igor Kushnir <igor...@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |RESOLVED Resolution|--- |FIXED Latest Commit| |https://invent.kde.org/kdev | |elop/kdevelop/-/commit/a152 | |4591a3d0d02a493c3742d2c772e | |9f7b50654 Version Fixed In| |5.14 --- Comment #6 from Igor Kushnir <igor...@gmail.com> --- Git commit a1524591a3d0d02a493c3742d2c772e9f7b50654 by Igor Kushnir. Committed on 08/03/2024 at 10:22. Pushed by igorkushnir into branch 'master'. BreakpointModel: complete document reload support This commit addresses the following issue and removes the FIXME comment that describes it: if a modified document is reloaded, and the user clicks a button other than "Discard" in the message box that appears, the moving cursors should not be reverted to their saved locations. When a modified document is reloaded, the user makes a Cancel/Discard/Save choice after the aboutToReload() signal is emitted. Therefore, BreakpointModel::aboutToReload() must not make any changes to breakpoints or breakpoint marks that depend on this user choice. Remove moving cursors during a reload later - in BreakpointModel::aboutToInvalidateMovingInterfaceContent() instead of BreakpointModel::aboutToReload(). If the user cancels reloading a modified document, it does not emit the signal aboutToInvalidateMovingInterfaceContent(), its moving cursors are not invalidated and breakpoints remain intact. If the user reloads a modified document and opts to save it (and overwrite possible changes on disk), BreakpointModel::documentSaved() is invoked and saves the breakpoints' tracked line numbers before aboutToInvalidateMovingInterfaceContent() removes the moving cursors. If the user reloads a modified document and opts to discard editor changes or reloads an unmodified document, the executed BreakpointModel code is almost unchanged, because these cases were already perfectly supported. The only consequential difference is that aboutToReload() inhibits mark change instead of removing all breakpoint marks in the reloaded document. That's because the breakpoint marks must not be removed in case the user cancels reloading. Unfortunately, not removing breakpoint marks in aboutToReload() lets KTextEditor::DocumentPrivate::documentReload() store in a local variable all of the document's breakpoint marks. The saving and restoring of breakpoint marks by KTextEditor is useless work, because BreakpointModel has a different notion/algorithm where breakpoint marks should be placed after the document is reloaded. There is no API to prevent this useless KTextEditor work. So BreakpointModel resorts to working around possible mark conflicts by removing all breakpoint marks in the document before adding them at correct locations in case of the Discard user choice. In case of the Save user choice or when an unmodified document is reloaded, KTextEditor restores breakpoint marks at correct locations. BreakpointModel still restores breakpoint marks again afterwards, because KTextEditor may choose to skip restoring some of the marks. This double restoration is safe, because KTextEditor::Document's member function addMark(int line, uint markType) does not change anything if a mark of the type `markType` is already set on the line `line`. Connect to 3 KTextEditor::Document's signals - aboutToReload(), aboutToInvalidateMovingInterfaceContent() and reloaded() in BreakpointModel::textDocumentCreated(). The downside of connecting to every open document's signals is that both the connecting itself and the work in the slots when the document is reloaded is useless if there are no breakpoints at its URL (which should be the case for most documents). I have considered and rejected connecting to these 3 signals in BreakpointModel::setupMovingCursor(), which is called only for documents that contain breakpoints. The problem is that a moving cursor is not set up for a breakpoint at a line out of the document's range. But reloading may increase the number of lines in the document and thus allow BreakpointModel::reloaded() to enable document line tracking for newly-in-range breakpoints. In the future, BreakpointModel should acquire a way to efficiently access all breakpoints in a given document. This would substantially reduce overhead for documents without breakpoints and allow to move the existing aboutToDeleteMovingInterfaceContent() connection from setupMovingCursor() to textDocumentCreated(). A unit test cannot make the Cancel/Discard/Save user choice programmatically instead of showing the Close Document warning dialog. Add semiautomatic tests and skip them by default. When a developer makes code changes that affect breakpoints in a reloaded modified document, [s]he can disable the QSKIP() call and run the tests. Extract two helper functions from TestBreakpointModel::testDocumentReload() and reuse them. The extracted code is practically unchanged. FIXED-IN: 5.14 M +6 -0 kdevplatform/debugger/breakpoint/breakpoint.cpp M +7 -0 kdevplatform/debugger/breakpoint/breakpoint.h M +107 -31 kdevplatform/debugger/breakpoint/breakpointmodel.cpp M +4 -3 kdevplatform/debugger/breakpoint/breakpointmodel.h M +170 -27 kdevplatform/debugger/tests/test_breakpointmodel.cpp M +8 -0 kdevplatform/debugger/tests/test_breakpointmodel.h https://invent.kde.org/kdevelop/kdevelop/-/commit/a1524591a3d0d02a493c3742d2c772e9f7b50654 -- You are receiving this mail because: You are watching all bug changes.