Skip to content

Commit a78d480

Browse files
committed
#1696 notesubfolders: preserve tag links on rename and move
Signed-off-by: Patrizio Bekerle <patrizio@bekerle.com>
1 parent 126f04e commit a78d480

3 files changed

Lines changed: 26 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## 26.4.16
44

5+
- Tag assignments are now preserved when a **note subfolder** is renamed,
6+
moved, or contains notes that are moved as part of a subfolder operation;
7+
the subfolder path update now uses a safe prefix-only replacement so that
8+
sibling folders sharing the same name prefix and notes whose path components
9+
happen to repeat the folder name are no longer incorrectly modified
10+
(for [#1696](https://github.com/pbek/QOwnNotes/issues/1696))
511
- Refactored the **Settings dialog** by extracting individual settings pages
612
into separate widget classes and moved them to a dedicated `widgets/settings`
713
directory for better code organization (for [#3570](https://github.com/pbek/QOwnNotes/issues/3570))

src/entities/notesubfolder.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ bool NoteSubFolder::rename(const QString& newName) {
178178
Note::updateQualifiedWikiLinksForSubfolderRename(oldRelativePath, newRelativePath);
179179
Note::updateRelativeMarkdownLinksForSubfolderRename(oldRelativePath, newRelativePath);
180180

181+
// Persist the new name to the database so that the re-index triggered
182+
// by the folder rename below can locate the existing row by its new
183+
// name and reuse it (instead of deleting the old row and creating a
184+
// fresh one with a new id, which would cause note rows to be
185+
// recreated and tag links to be temporarily unresolvable).
186+
store();
187+
181188
// rename the note subfolder
182189
const bool ret = QDir().rename(oldPath, newPath);
183190

src/entities/tag.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,17 +1288,27 @@ bool Tag::renameNoteFileNamesOfLinks(const QString &oldFileName, const QString &
12881288

12891289
/**
12901290
* Renames the note sub folder paths of note links
1291+
*
1292+
* Uses prefix-only substitution to avoid accidentally modifying sibling paths
1293+
* that share the same prefix (e.g. renaming "work" must not affect "workplace"),
1294+
* and to prevent the global replace() from corrupting paths that contain the
1295+
* old folder name in a deeper component (e.g. "A/A/note" when renaming "A").
12911296
*/
12921297
bool Tag::renameNoteSubFolderPathsOfLinks(const QString &oldPath, const QString &newPath) {
12931298
QSqlDatabase db = DatabaseService::getNoteFolderDatabase();
12941299
QSqlQuery query(db);
1300+
// Replace only the prefix: match the exact path or direct/deep children
1301+
// (separated by "/"), then concatenate newPath with the remainder of the
1302+
// original string so that inner occurrences of the old name are untouched.
12951303
query.prepare(
12961304
QStringLiteral("UPDATE noteTagLink SET note_sub_folder_path = "
1297-
"replace(note_sub_folder_path, :oldPath, :newPath) WHERE "
1298-
"note_sub_folder_path LIKE :oldPathLike"));
1305+
":newPath || substr(note_sub_folder_path, length(:oldPath2) + 1) "
1306+
"WHERE note_sub_folder_path = :oldPath "
1307+
"OR note_sub_folder_path LIKE :oldPathChildLike"));
12991308

13001309
query.bindValue(QStringLiteral(":oldPath"), oldPath);
1301-
query.bindValue(QStringLiteral(":oldPathLike"), oldPath + "%");
1310+
query.bindValue(QStringLiteral(":oldPath2"), oldPath);
1311+
query.bindValue(QStringLiteral(":oldPathChildLike"), oldPath + "/%");
13021312
query.bindValue(QStringLiteral(":newPath"), newPath);
13031313

13041314
if (!query.exec()) {

0 commit comments

Comments
 (0)