From 25829d1351d404933146416bb4bace90d7fa0db9 Mon Sep 17 00:00:00 2001 From: Jeff Davidson Date: Sat, 5 Jun 2021 11:29:29 -0700 Subject: [PATCH] Improve handling of different capitalizations of "Across" and "Down". When setting a ClueList, normalize them to the canonical "Across" and "Down" as is used elsewhere in XWord. This fixes features like reuse of existing settings for the Across and Down clue panes and saving the file as an Across Lite .puz file. Note that this results in the displayed clue list using the canonical name and not the provided name, since MyFrame::ShowClues is built around using the keys and not the titles. However, this is only a minor cosmetic difference that seems harder to fix. --- puz/Clue.hpp | 14 ++++++++++++-- puz/puzstring.cpp | 15 +++++++++++++++ puz/puzstring.hpp | 2 ++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/puz/Clue.hpp b/puz/Clue.hpp index 7f4bb266..854c0e3b 100644 --- a/puz/Clue.hpp +++ b/puz/Clue.hpp @@ -147,8 +147,18 @@ class PUZ_API Clues : public std::map ClueList & SetClueList(const string_t & direction, const ClueList & cluelist) { - operator[](direction) = cluelist; - ClueList & ret = operator[](direction); + // Normalize different capitalizations of "Across" and "Down", since these have special meaning. + // We still retain the original direction in the title field. + string_t canonical_direction; + if (CaseInsensitiveEquals(direction, puzT("Across"))) + canonical_direction = puzT("Across"); + else if (CaseInsensitiveEquals(direction, puzT("Down"))) + canonical_direction = puzT("Down"); + else + canonical_direction = direction; + + operator[](canonical_direction) = cluelist; + ClueList & ret = operator[](canonical_direction); if (ret.GetTitle().empty()) ret.SetTitle(direction); return ret; diff --git a/puz/puzstring.cpp b/puz/puzstring.cpp index b0f15304..0d41678f 100644 --- a/puz/puzstring.cpp +++ b/puz/puzstring.cpp @@ -318,6 +318,21 @@ bool EndsWith(const string_t & str, const string_t & cmp) str.compare(str.size() - cmp.size(), cmp.size(), cmp) == 0; } +bool CaseInsensitiveEquals(const string_t& a, const string_t& b) +{ + unsigned int sz = a.size(); + if (b.size() != sz) + return false; + for (unsigned int i = 0; i < sz; ++i) +#if PUZ_UNICODE + if (towlower(a[i]) != towlower(b[i])) +#else + if (tolower(a[i]) != tolower(b[i])) +#endif + return false; + return true; +} + //---------------------------------------------------------------------------- // Convert between formatted / unformatted //---------------------------------------------------------------------------- diff --git a/puz/puzstring.hpp b/puz/puzstring.hpp index b86f4a26..22ba6c49 100644 --- a/puz/puzstring.hpp +++ b/puz/puzstring.hpp @@ -84,6 +84,8 @@ int ToInt(const string_t & str); bool StartsWith(const string_t & str, const string_t & cmp); bool EndsWith(const string_t & str, const string_t & cmp); +bool CaseInsensitiveEquals(const string_t& a, const string_t& b); + // XML stuff enum { UNESCAPE_BR = 1,