Skip to content

Commit c1d3c7b

Browse files
wjyrichBLumia
authored andcommitted
feat: add search for Uppercase and modify deepin-XXX logic.
as title. Logs:
1 parent 95fbc8c commit c1d3c7b

6 files changed

Lines changed: 99 additions & 30 deletions

File tree

src/ddeintegration/appmgr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ static AppMgr::AppItem *parseDBus2AppItem(const ObjectInterfaceMap &source)
7979

8080
// fallback to Name if GenericName is empty, only for X_Deepin_Vendor equals to "deepin".
8181
const auto deepinVendor = parseDBusField<QString>(appInfo, u8"X_Deepin_Vendor");
82+
item->vendor = deepinVendor ? deepinVendor.value() : QString();
83+
84+
// Get GenericName field
85+
const auto genericNameMap = parseDBusField<QStringMap>(appInfo, u8"GenericName");
86+
item->genericName = genericNameMap ? parseName(genericNameMap.value()) : QString();
87+
8288
item->displayName = getDisplayName(deepinVendor && deepinVendor.value() == QStringLiteral("deepin"),
8389
parseDBusField<QStringMap>(appInfo, u8"Name").value(),
8490
parseDBusField<QStringMap>(appInfo, u8"GenericName").value());

src/ddeintegration/appmgr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class AppMgr : public QObject
3333
qint64 launchedTimes = 0;
3434
bool isAutoStart = false;
3535
QString appId;
36+
QString vendor;
37+
QString genericName;
3638
};
3739

3840
static AppMgr *instance();

src/models/appitem.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,26 @@ void AppItem::setIsAutoStart(bool autostart)
117117
setData(autostart, AppItem::IsAutoStartRole);
118118
}
119119

120+
const QString AppItem::vendor() const
121+
{
122+
return data(AppItem::VendorRole).toString();
123+
}
124+
125+
void AppItem::setVendor(const QString &vendor)
126+
{
127+
setData(vendor, AppItem::VendorRole);
128+
}
129+
130+
const QString AppItem::genericName() const
131+
{
132+
return data(AppItem::GenericNameRole).toString();
133+
}
134+
135+
void AppItem::setGenericName(const QString &genericName)
136+
{
137+
setData(genericName, AppItem::GenericNameRole);
138+
}
139+
120140
// assign/update data from another AppItem object
121141
// assume the desktopId is the same, will update other data.
122142
// doesn't take the ownership of the passed appItem.
@@ -133,5 +153,7 @@ void AppItem::updateData(const AppItem *appItem)
133153
setData(appItem->data(AppItem::LastLaunchedTimeRole), AppItem::LastLaunchedTimeRole);
134154
setData(appItem->data(AppItem::LaunchedTimesRole), AppItem::LaunchedTimesRole);
135155
setData(appItem->data(AppItem::IsAutoStartRole), AppItem::IsAutoStartRole);
156+
setData(appItem->data(AppItem::VendorRole), AppItem::VendorRole);
157+
setData(appItem->data(AppItem::GenericNameRole), AppItem::GenericNameRole);
136158
}
137159

src/models/appitem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class AppItem : public QStandardItem
2323
LastLaunchedTimeRole,
2424
LaunchedTimesRole,
2525
IsAutoStartRole,
26+
VendorRole,
27+
GenericNameRole,
2628
ModelExtendedRole = 0x1000
2729
};
2830
Q_ENUM(Roles)
@@ -70,6 +72,10 @@ class AppItem : public QStandardItem
7072
void setLaunchedTimes(qint64 times);
7173
bool isAutoStart() const;
7274
void setIsAutoStart(bool autostart);
75+
const QString vendor() const;
76+
void setVendor(const QString & vendor);
77+
const QString genericName() const;
78+
void setGenericName(const QString & genericName);
7379
void updateData(const AppItem * appItem);
7480
};
7581

src/models/appsmodel.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ AppsModel::AppsModel(QObject *parent)
5454
{AppItem::LastLaunchedTimeRole, QByteArrayLiteral("lastLaunchedTime")},
5555
{AppItem::LaunchedTimesRole, QByteArrayLiteral("launchedTimes")},
5656
{AppItem::IsAutoStartRole, QByteArrayLiteral("autoStart")},
57+
{AppItem::VendorRole, QByteArrayLiteral("vendor")},
58+
{AppItem::GenericNameRole, QByteArrayLiteral("genericName")},
5759
{AppsModel::TransliteratedRole, QByteArrayLiteral("transliterated")}
5860
});
5961
setItemRoleNames(defaultRoleNames);
@@ -239,6 +241,8 @@ QList<AppItem *> AppsModel::allAppInfosShouldBeShown() const
239241
item->setLastLaunchedTime(appItem->lastLaunchedTime);
240242
item->setLaunchedTimes(appItem->launchedTimes);
241243
item->setIsAutoStart(appItem->isAutoStart);
244+
item->setVendor(appItem->vendor);
245+
item->setGenericName(appItem->genericName);
242246
items.append(item);
243247
}
244248
return items;

src/models/searchfilterproxymodel.cpp

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,26 @@ bool SearchFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &
2525

2626
const QString & displayName = modelIndex.data(Qt::DisplayRole).toString();
2727
const QString & name = modelIndex.data(AppsModel::NameRole).toString();
28+
const QString & vendor = modelIndex.data(AppItem::VendorRole).toString();
29+
const QString & genericName = modelIndex.data(AppItem::GenericNameRole).toString();
2830
const QString & transliterated = modelIndex.data(AppsModel::AllTransliteratedRole).toString();
2931
const QString & jianpin = Dtk::Core::firstLetters(displayName).join(',');
3032

31-
auto nameCopy = name;
32-
nameCopy = nameCopy.toLower();
33-
nameCopy.replace(" ", "");
34-
3533
QString searchPatternDelBlank = searchPattern.pattern().toLower().remove(" ");
3634

37-
// Get first letters of each word in displayName
38-
QStringList words = displayName.split(" ", Qt::SkipEmptyParts);
35+
// Choose which name to use for matching based on search input and vendor
36+
QString targetName;
37+
if(vendor == "deepin") {
38+
targetName = genericName;
39+
if(targetName.isEmpty()) {
40+
targetName = name;
41+
}
42+
}else{
43+
targetName = name;
44+
}
45+
46+
// Get first letters of each word in targetName eg: visual studio code -> vsc
47+
QStringList words = targetName.split(" ", Qt::SkipEmptyParts);
3948
QString nameFirstLetters;
4049
for (const QString &word : words) {
4150
if (!word.isEmpty()) {
@@ -46,19 +55,21 @@ bool SearchFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &
4655
}
4756
}
4857

49-
// Check for number or English prefix matches only
50-
QRegularExpression searchNumberCheck("\\d+$");
51-
QRegularExpression searchEnglishCheck("^[a-zA-Z\\s]+$");
58+
QRegularExpression searchNumberCheck("^\\d+$");
5259
bool isNumberSearch = searchNumberCheck.match(searchPatternDelBlank).hasMatch();
60+
61+
QRegularExpression searchEnglishCheck("^[a-zA-Z0-9\\s]+$");
5362
bool isEnglishSearch = searchEnglishCheck.match(searchPattern.pattern()).hasMatch();
5463

64+
QRegularExpression searchHasLetterCheck("[a-zA-Z]");
65+
bool hasLetter = searchHasLetterCheck.match(searchPattern.pattern()).hasMatch();
66+
5567
if (isNumberSearch || isEnglishSearch) {
5668
bool hasMatch = false;
57-
58-
// Handle number prefix matching
69+
// Handle number prefix matching eg: 360zip
5970
if (isNumberSearch) {
6071
QRegularExpression numberRegex("\\d+");
61-
QRegularExpressionMatchIterator matches = numberRegex.globalMatch(displayName);
72+
QRegularExpressionMatchIterator matches = numberRegex.globalMatch(targetName);
6273

6374
while (matches.hasNext()) {
6475
QRegularExpressionMatch match = matches.next();
@@ -72,33 +83,42 @@ bool SearchFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &
7283

7384
// Handle English prefix matching
7485
if (isEnglishSearch) {
75-
// Remove spaces and convert to lowercase for comparison
76-
QString displayNameLower = displayName.toLower().remove(" ");
77-
86+
QString targetNameLower = targetName.toLower().remove(" ");
87+
88+
// Extract all capitalized words from displayName (both at beginning and middle)
89+
//eg: x11Vnc Server -> VNC
90+
QString targetNameUpper;
91+
QRegularExpression capitalizedWordRegex("\\b[A-Z][A-Za-z0-9]*");
92+
QRegularExpressionMatchIterator capitalizedMatches = capitalizedWordRegex.globalMatch(targetName);
93+
94+
while (capitalizedMatches.hasNext()) {
95+
QRegularExpressionMatch match = capitalizedMatches.next();
96+
QString capitalizedWord = match.captured(0).toLower();
97+
if (!targetNameUpper.isEmpty()) {
98+
targetNameUpper += " ";
99+
}
100+
targetNameUpper += capitalizedWord;
101+
}
102+
103+
78104
// Check prefix matching for various name formats
79-
if (displayNameLower.startsWith(searchPatternDelBlank) ||
80-
nameCopy.startsWith(searchPatternDelBlank) ||
105+
if (
106+
displayName.startsWith(searchPatternDelBlank) ||
107+
targetNameLower.startsWith(searchPatternDelBlank) ||
81108
transliterated.startsWith(searchPatternDelBlank) ||
82109
jianpin.startsWith(searchPatternDelBlank) ||
110+
targetNameUpper.startsWith(searchPatternDelBlank) ||
83111
nameFirstLetters.startsWith(searchPatternDelBlank)) {
84112
return true;
85113
}
86114

87-
// Also check if search pattern matches the prefix of any word in displayName
115+
// Also check if search pattern matches the prefix of any word in targetName
88116
for (const QString &word : words) {
89117
if (word.toLower().startsWith(searchPatternDelBlank)) {
90118
return true;
91119
}
92120
}
93121

94-
// Also check if search pattern matches the prefix of any word in name
95-
QStringList nameWords = name.split(" ", Qt::SkipEmptyParts);
96-
for (const QString &word : nameWords) {
97-
if (word.toLower().startsWith(searchPatternDelBlank)) {
98-
return true;
99-
}
100-
}
101-
102122
// Also check if search pattern matches the prefix of any word in transliterated
103123
QStringList transliteratedWords = transliterated.split(" ", Qt::SkipEmptyParts);
104124
for (const QString &word : transliteratedWords) {
@@ -107,17 +127,26 @@ bool SearchFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &
107127
}
108128
}
109129

110-
hasMatch = true; // English content was found
130+
// For English searches with letters, if prefix matching fails, fall back to contains matching
131+
if (hasLetter && (displayName.contains(searchPatternDelBlank) ||
132+
targetNameLower.contains(searchPatternDelBlank) ||
133+
transliterated.contains(searchPatternDelBlank) ||
134+
jianpin.contains(searchPatternDelBlank) ||
135+
nameFirstLetters.contains(searchPatternDelBlank))) {
136+
return true;
137+
}
138+
139+
hasMatch = true;
111140
}
112141

113-
// If we had matches but none were prefix matches, return false
114-
if (hasMatch) {
142+
// If we had number matches but none were prefix matches, return false
143+
if (hasMatch && isNumberSearch) {
115144
return false;
116145
}
117146
}
118147

119148
return displayName.contains(searchPatternDelBlank) ||
120-
nameCopy.contains(searchPatternDelBlank) ||
149+
targetName.contains(searchPatternDelBlank) ||
121150
transliterated.contains(searchPatternDelBlank) ||
122151
jianpin.contains(searchPatternDelBlank) ||
123152
nameFirstLetters.contains(searchPatternDelBlank);

0 commit comments

Comments
 (0)