File indexing completed on 2024-04-21 03:54:20
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2008 Chusslove Illich <caslav.ilic@gmx.net> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <common_helpers_p.h> 0008 0009 // If pos points to alphanumeric X in "...(X)...", which is preceded or 0010 // followed only by non-alphanumerics, then "(X)" gets removed. 0011 static QString removeReducedCJKAccMark(const QString &label, int pos) 0012 { 0013 if (pos > 0 && pos + 1 < label.length() // 0014 && label[pos - 1] == QLatin1Char('(') // 0015 && label[pos + 1] == QLatin1Char(')') // 0016 && label[pos].isLetterOrNumber()) { 0017 // Check if at start or end, ignoring non-alphanumerics. 0018 int len = label.length(); 0019 int p1 = pos - 2; 0020 while (p1 >= 0 && !label[p1].isLetterOrNumber()) { 0021 --p1; 0022 } 0023 ++p1; 0024 int p2 = pos + 2; 0025 while (p2 < len && !label[p2].isLetterOrNumber()) { 0026 ++p2; 0027 } 0028 --p2; 0029 0030 const QStringView labelView(label); 0031 if (p1 == 0) { 0032 return labelView.left(pos - 1) + labelView.mid(p2 + 1); 0033 } else if (p2 + 1 == len) { 0034 return labelView.left(p1) + labelView.mid(pos + 2); 0035 } 0036 } 0037 return label; 0038 } 0039 0040 QString removeAcceleratorMarker(const QString &label_) 0041 { 0042 QString label = label_; 0043 0044 int p = 0; 0045 bool accmarkRemoved = false; 0046 while (true) { 0047 p = label.indexOf(QLatin1Char('&'), p); 0048 if (p < 0 || p + 1 == label.length()) { 0049 break; 0050 } 0051 0052 const QStringView labelView(label); 0053 const QChar marker = label.at(p + 1); 0054 if (marker.isLetterOrNumber()) { 0055 // Valid accelerator. 0056 label = labelView.left(p) + labelView.mid(p + 1); 0057 0058 // May have been an accelerator in CJK-style "(&X)" 0059 // at the start or end of text. 0060 label = removeReducedCJKAccMark(label, p); 0061 0062 accmarkRemoved = true; 0063 } else if (marker == QLatin1Char('&')) { 0064 // Escaped accelerator marker. 0065 label = labelView.left(p) + labelView.mid(p + 1); 0066 } 0067 0068 ++p; 0069 } 0070 0071 // If no marker was removed, and there are CJK characters in the label, 0072 // also try to remove reduced CJK marker -- something may have removed 0073 // ampersand beforehand. 0074 if (!accmarkRemoved) { 0075 bool hasCJK = false; 0076 for (const QChar c : std::as_const(label)) { 0077 if (c.unicode() >= 0x2e00) { // rough, but should be sufficient 0078 hasCJK = true; 0079 break; 0080 } 0081 } 0082 if (hasCJK) { 0083 p = 0; 0084 while (true) { 0085 p = label.indexOf(QLatin1Char('('), p); 0086 if (p < 0) { 0087 break; 0088 } 0089 label = removeReducedCJKAccMark(label, p + 1); 0090 ++p; 0091 } 0092 } 0093 } 0094 0095 return label; 0096 }