ProjectTextWalk.h header

#include <ew/app/ProjectTextWalk.h>

Namespace ew::app

ObjectReplacement struct

struct ew::app::ObjectReplacement

A replacement over one object: the command that performs it, and how many matches it covers.

Members

std::unique_ptr<ew::core::undo::Command> ew::app::search::ObjectReplacement::command

The command, or null when nothing in the object matched.

int ew::app::search::ObjectReplacement::count = 0

How many matches the command replaces.

ObjectText struct

struct ew::app::ObjectText

Every searchable text field of one object, grouped so a result list can group by object.

Members

ew::core::foundation::ContentId ew::app::search::ObjectText::id

The object the text belongs to.

ew::core::content::ContentType ew::app::search::ObjectText::kind =

What kind of object it is, so a result list can say what it found and a scope can narrow to one kind. ew::core::content::ContentType, never a second enum beside it.

QString ew::app::search::ObjectText::title

The object's display title, for the group heading.

std::vector<TextField> ew::app::search::ObjectText::fields

The object's searchable fields, in the order a reader meets them.

TextField struct

struct ew::app::TextField

One piece of writer-visible text that a project-wide find and replace can reach.

Members

QString ew::app::search::TextField::where

Where in the object the text lives, in the writer's terms: "Body", "Alias", "Cell B4", "Line 3", "Pin name". Shown beside a match so a result says WHAT matched, not just where.

QString ew::app::search::TextField::text

The text itself.

TextScope struct

struct ew::app::TextScope

What a project-wide find and replace is allowed to look at.

Every field narrows; an unset field does not. A default-constructed scope is the whole project, which is what the dialog opens on. They compose, so "entities in the Characters category tagged draft" is one scope rather than three searches.

Narrowing exists because replace is the dangerous half. A writer renaming a term across a 300-object project cannot review a thousand matches by eye, and the only alternative to a scope is running it everywhere and hoping – which is how a replace reaches the one place it should not have.

Members

std::optional<ew::core::content::ContentType> ew::app::search::TextScope::type

Only objects of this type, or every type when unset.

ew::core::foundation::CategoryId ew::app::search::TextScope::category

Only entities in this category; ignored when null.

QString ew::app::search::TextScope::tag

Only objects carrying this tag; ignored when empty.

QString ew::app::search::TextScope::audience

Only objects restricted to this audience; ignored when empty.

An object with NO audiences is visible to everyone, and does NOT match a named audience: narrowing to "GM notes" must not sweep in every unrestricted object in the project.

QString ew::app::search::TextScope::status

Only documents at this status; ignored when empty. No other content type has one.

std::vector<ew::core::foundation::ContentId> ew::app::search::TextScope::selection

Only these objects; ignored when empty. This is what "the current selection" means.

Functions

bool ew::app::search::inScope(const ew::core::project::Project &project, ew::core::foundation::ContentId id, const TextScope &scope)

Whether the object id is inside scope. Every field the scope sets has to hold.

std::vector< ObjectText > ew::app::search::projectText(const ew::core::project::Project &project, const TextScope &scope={})

Every object in project within scope whose text a find and replace can reach.

All seventeen content types, not just documents. Find in Project was document-keyed throughout – it could not see an entity's name, a line of dialogue, a spreadsheet cell, a task's description, a map pin, a timeline event, a comment or a caption – which made it narrower than the search box beside it, an asymmetry a writer hits on the first day they rename a character.

Objects with no text at all are omitted rather than returned empty, so a caller can treat the result as "everywhere there is something to find".

ObjectReplacement ew::app::search::replaceInObject(ew::core::project::Project &project, ew::core::foundation::ContentId id, const QRegularExpression &regex, const QString &replacement)

Replaces every match of regex in the text of the object id, returning one command for the whole object.

One command per OBJECT, never per field. Several fields of one object usually live inside a single value that has to be written back whole – every cell of a spreadsheet is one cells() vector, every line of a scene is one nodes() vector. Two commands each computed from the object's original state would have the second silently discard the first, so a replace touching two cells would land only one of them and the writer would have no way to tell.

replacement may use \1..\9 for the pattern's capture groups (see expandBackreferences).