File indexing completed on 2024-05-05 04:41:57

0001 // SPDX-FileCopyrightText: 2020 Carson Black <uhhadd@gmail.com>
0002 //
0003 // SPDX-License-Identifier: LGPL-2.0-or-later
0004 
0005 #include "nameutils.h"
0006 #include <QDebug>
0007 #include <QMap>
0008 #include <QQuickStyle>
0009 #include <QTextBoundaryFinder>
0010 #include <QVector>
0011 
0012 bool contains(const QString &str, QChar::Script s)
0013 {
0014     for (auto rune : str) {
0015         if (rune.script() == s) {
0016             return true;
0017         }
0018     }
0019     return false;
0020 }
0021 
0022 QString NameUtils::initialsFromString(const QString &string)
0023 {
0024     // "" -> ""
0025     QString normalized = string.trimmed();
0026     if (normalized.isEmpty()) {
0027         return {};
0028     }
0029 
0030     normalized = string.normalized(QString::NormalizationForm_D);
0031 
0032     if (normalized.startsWith(QLatin1Char('#')) || normalized.startsWith(QLatin1Char('@'))) {
0033         normalized.remove(0, 1);
0034     }
0035 
0036     // Names written with Han and Hangul characters generally can be initialised by taking the
0037     // first character
0038     if (contains(normalized, QChar::Script_Han) || contains(normalized, QChar::Script_Hangul)) {
0039         return normalized.at(0);
0040     }
0041 
0042     // "FirstName Name Name LastName"
0043     normalized = normalized.trimmed();
0044 
0045     // Remove stuff inside parantheses
0046     normalized = normalized.split(QLatin1Char('('))[0];
0047 
0048     if (normalized.isEmpty()) {
0049         return {};
0050     }
0051 
0052     if (normalized.contains(QLatin1Char(' '))) {
0053         // "FirstName Name Name LastName" -> "FirstName" "Name" "Name" "LastName"
0054 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0055         const auto split = QStringView(normalized).split(QLatin1Char(' '));
0056 #else
0057         const auto split = normalized.splitRef(QLatin1Char(' '));
0058 #endif
0059 
0060         // "FirstName"
0061         auto first = split.first();
0062         // "LastName"
0063         auto last = split.last();
0064         if (first.isEmpty()) {
0065             // "" "LastName" -> "L"
0066             return QString(last.front()).toUpper();
0067         }
0068         if (last.isEmpty()) {
0069             // "FirstName" "" -> "F"
0070             return QString(first.front()).toUpper();
0071         }
0072         // "FirstName" "LastName" -> "FL"
0073         return (QString(first.front()) + last.front()).toUpper();
0074         // "OneName"
0075     } else {
0076         // "OneName" -> "O"
0077         return QString(normalized.front()).toUpper();
0078     }
0079 }
0080 
0081 /* clang-format off */
0082 const QMap<QString,QList<QColor>> c_colors = {
0083     {
0084         QStringLiteral("default"),
0085         {
0086             QColor("#e93a9a"),
0087             QColor("#e93d58"),
0088             QColor("#e9643a"),
0089             QColor("#ef973c"),
0090             QColor("#e8cb2d"),
0091             QColor("#b6e521"),
0092             QColor("#3dd425"),
0093             QColor("#00d485"),
0094             QColor("#00d3b8"),
0095             QColor("#3daee9"),
0096             QColor("#b875dc"),
0097             QColor("#926ee4"),
0098         }
0099     },
0100     {
0101         QStringLiteral("Material"),
0102         {
0103             QColor("#f44336"),
0104             QColor("#e91e63"),
0105             QColor("#9c27b0"),
0106             QColor("#673ab7"),
0107             QColor("#3f51b5"),
0108             QColor("#2196f3"),
0109             QColor("#03a9f4"),
0110             QColor("#00bcd4"),
0111             QColor("#009688"),
0112             QColor("#4caf50"),
0113             QColor("#8bc34a"),
0114             QColor("#cddc39"),
0115             QColor("#ffeb3b"),
0116             QColor("#ffc107"),
0117             QColor("#ff9800"),
0118             QColor("#ff5722"),
0119         }
0120     }
0121 };
0122 /* clang-format on */
0123 
0124 QList<QColor> grabColors()
0125 {
0126     if (c_colors.contains(QQuickStyle::name())) {
0127         return c_colors[QQuickStyle::name()];
0128     }
0129     return c_colors[QStringLiteral("default")];
0130 }
0131 
0132 auto NameUtils::colorsFromString(const QString &string) -> QColor
0133 {
0134     // We use a hash to get a "random" number that's always the same for
0135     // a given string.
0136     auto hash = qHash(string);
0137     // hash modulo the length of the colors list minus one will always get us a valid
0138     // index
0139     auto index = hash % (grabColors().length() - 1);
0140     // return a colour
0141     return grabColors()[index];
0142 }
0143 
0144 auto NameUtils::isStringUnsuitableForInitials(const QString &string) -> bool
0145 {
0146     if (string.isEmpty()) {
0147         return true;
0148     }
0149 
0150     bool isNumber;
0151     string.toFloat(&isNumber);
0152     if (isNumber) {
0153         return true;
0154     }
0155 
0156     const auto scripts = QList<QChar::Script>{QChar::Script_Common, QChar::Script_Inherited, QChar::Script_Latin, QChar::Script_Han, QChar::Script_Hangul, QChar::Script_Cyrillic};
0157 
0158     for (auto character : string) {
0159         if (!scripts.contains(character.script())) {
0160             return true;
0161         }
0162     }
0163     return false;
0164 }
0165 
0166 #include "moc_nameutils.cpp"