KI18n

common_helpers.cpp
1 /* This file is part of the KDE libraries
2  SPDX-FileCopyrightText: 2008 Chusslove Illich <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include <common_helpers_p.h>
8 
9 // If pos points to alphanumeric X in "...(X)...", which is preceded or
10 // followed only by non-alphanumerics, then "(X)" gets removed.
11 static QString removeReducedCJKAccMark(const QString &label, int pos)
12 {
13  if (pos > 0 && pos + 1 < label.length() //
14  && label[pos - 1] == QLatin1Char('(') //
15  && label[pos + 1] == QLatin1Char(')') //
16  && label[pos].isLetterOrNumber()) {
17  // Check if at start or end, ignoring non-alphanumerics.
18  int len = label.length();
19  int p1 = pos - 2;
20  while (p1 >= 0 && !label[p1].isLetterOrNumber()) {
21  --p1;
22  }
23  ++p1;
24  int p2 = pos + 2;
25  while (p2 < len && !label[p2].isLetterOrNumber()) {
26  ++p2;
27  }
28  --p2;
29 
30  const QStringView labelView(label);
31  if (p1 == 0) {
32  return labelView.left(pos - 1) + labelView.mid(p2 + 1);
33  } else if (p2 + 1 == len) {
34  return labelView.left(p1) + labelView.mid(pos + 2);
35  }
36  }
37  return label;
38 }
39 
40 QString removeAcceleratorMarker(const QString &label_)
41 {
42  QString label = label_;
43 
44  int p = 0;
45  bool accmarkRemoved = false;
46  while (true) {
47  p = label.indexOf(QLatin1Char('&'), p);
48  if (p < 0 || p + 1 == label.length()) {
49  break;
50  }
51 
52  const QStringView labelView(label);
53  const QChar marker = label.at(p + 1);
54  if (marker.isLetterOrNumber()) {
55  // Valid accelerator.
56  label = labelView.left(p) + labelView.mid(p + 1);
57 
58  // May have been an accelerator in CJK-style "(&X)"
59  // at the start or end of text.
60  label = removeReducedCJKAccMark(label, p);
61 
62  accmarkRemoved = true;
63  } else if (marker == QLatin1Char('&')) {
64  // Escaped accelerator marker.
65  label = labelView.left(p) + labelView.mid(p + 1);
66  }
67 
68  ++p;
69  }
70 
71  // If no marker was removed, and there are CJK characters in the label,
72  // also try to remove reduced CJK marker -- something may have removed
73  // ampersand beforehand.
74  if (!accmarkRemoved) {
75  bool hasCJK = false;
76  for (const QChar c : std::as_const(label)) {
77  if (c.unicode() >= 0x2e00) { // rough, but should be sufficient
78  hasCJK = true;
79  break;
80  }
81  }
82  if (hasCJK) {
83  p = 0;
84  while (true) {
85  p = label.indexOf(QLatin1Char('('), p);
86  if (p < 0) {
87  break;
88  }
89  label = removeReducedCJKAccMark(label, p + 1);
90  ++p;
91  }
92  }
93  }
94 
95  return label;
96 }
bool isLetterOrNumber() const const
int length() const const
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
QString label(StandardShortcut id)
QString left(int n) const const
const QChar at(int position) const const
QString mid(int position, int n) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Sep 23 2023 04:12:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.