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