File indexing completed on 2024-04-28 15:27:40

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