[KPIMTextEdit/FindBar] Respect rich formatting and user settings when replacing all
ClosedPublic

Authored by poboiko on May 1 2020, 6:05 AM.

Details

Summary

Instead of converting document to plain text, just loop over all encounters of the search string in the document and replace those.
Otherwise we will lose all formatting in RichTextEditor.

This way we're also able to respect the search settings (case sensitivity, whole word search).
Also, provide user with a visual indication showing how many replacements were made (the same way Kate/KWrite does it).
The latter two points also apply PlainTextEditFindBar.

(in principle, to avoid code duplication, we can move this to FindBarBase.
We only need to access mView->document(), which depends on the underlying text widget,
so we could add a virtual QTextDocument *document() method to FindBarBase and reimplement it)

Test Plan

Tested case-sensitive and regular expression Replace All on a rich-text document (having a list is already sufficient),
the formatting is not messed up

Diff Detail

Repository
R86 PIM: Text Editor
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
poboiko created this revision.May 1 2020, 6:05 AM
Restricted Application added a project: KDE PIM. · View Herald TranscriptMay 1 2020, 6:05 AM
poboiko requested review of this revision.May 1 2020, 6:05 AM
dvratil requested changes to this revision.May 1 2020, 12:42 PM
dvratil added a subscriber: dvratil.

If the code is shared, why not put it into a shared function that both editors can call? As fat as I can see, the function would only need the QTextDocument and the mFindWidget as inputs and would return the number of replacements made, which you can then use to emit the signal.

This revision now requires changes to proceed.May 1 2020, 12:42 PM

If the code is shared, why not put it into a shared function that both editors can call? As fat as I can see, the function would only need the QTextDocument and the mFindWidget as inputs and would return the number of replacements made, which you can then use to emit the signal.

That's what I've tried to suggest originally:

(in principle, to avoid code duplication, we can move this to FindBarBase. We only need to access mView->document(), which depends on the underlying text widget, so we could add a virtual QTextDocument *document() method to FindBarBase and reimplement it)

But now as I can see it might be not the best place: it would seem like TextEditFindBarBase is supposed to be as backend-agnostic as possible (not even necessary QTextDocument-based...). Do you have suggestions, where should I put it then?

Actually, there is a larger issue with that: the RichTextEditFindBar and PlainTextEditFindBar classes are completely equivalent (up to naming), not only the added method :(
(that stems from the fact that both QTextEdit and QPlainTextEdit have similar interface: we only use methods document, textCursor, moveCursor, setTextCursor, isReadOnly, find, and they are present in both classes).

mlaurent accepted this revision.May 1 2020, 5:32 PM

Could easily be put into some FindUtils.cpp file or so, doesn't need to be in the TextEditFindBarBase just because it's a baseclass.

poboiko updated this revision to Diff 81792.May 3 2020, 12:16 PM

Move replacement code that is common both to PlainTextEditFindBar and RichTextEditFindBar
to dedicated file texteditor/commonwidget/findutils.cpp.

mlaurent requested changes to this revision.May 3 2020, 12:43 PM
mlaurent added inline comments.
src/texteditor/commonwidget/findutils.h
38

Add Q_REQUIRED_RESULT

This revision now requires changes to proceed.May 3 2020, 12:43 PM
poboiko updated this revision to Diff 81851.May 4 2020, 9:17 AM

Add Q_REQUIRED_RESULT

mlaurent accepted this revision.May 4 2020, 12:10 PM
This revision was not accepted when it landed; it landed in state Needs Review.May 4 2020, 4:42 PM
This revision was automatically updated to reflect the committed changes.