Merge "Trim all whitespace from titles and labels." into ub-launcher3-burnaby
This commit is contained in:
@@ -29,8 +29,7 @@ class AppNameComparator {
|
||||
mAppNameComparator = new Comparator<AppInfo>() {
|
||||
public final int compare(AppInfo a, AppInfo b) {
|
||||
// Order by the title
|
||||
int result = collator.compare(a.title.toString().trim(),
|
||||
b.title.toString().trim());
|
||||
int result = collator.compare(a.title.toString(), b.title.toString());
|
||||
if (result == 0) {
|
||||
// If two apps have the same title, then order by the component name
|
||||
result = a.componentName.compareTo(b.componentName);
|
||||
@@ -349,7 +348,7 @@ public class AlphabeticalAppsList {
|
||||
int appIndex = 0;
|
||||
int numApps = mApps.size();
|
||||
for (AppInfo info : mApps) {
|
||||
String sectionName = mIndexer.computeSectionName(info.title.toString().trim());
|
||||
String sectionName = mIndexer.computeSectionName(info.title);
|
||||
|
||||
// Check if we want to retain this app
|
||||
if (mFilter != null && !mFilter.retainApp(info, sectionName)) {
|
||||
|
||||
@@ -105,7 +105,7 @@ public class AppInfo extends ItemInfo {
|
||||
public AppInfo(AppInfo info) {
|
||||
super(info);
|
||||
componentName = info.componentName;
|
||||
title = info.title.toString();
|
||||
title = Utilities.trim(info.title);
|
||||
intent = new Intent(info.intent);
|
||||
flags = info.flags;
|
||||
firstInstallTime = info.firstInstallTime;
|
||||
@@ -114,7 +114,7 @@ public class AppInfo extends ItemInfo {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApplicationInfo(title=" + title.toString() + " id=" + this.id
|
||||
return "ApplicationInfo(title=" + title + " id=" + this.id
|
||||
+ " type=" + this.itemType + " container=" + this.container
|
||||
+ " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY
|
||||
+ " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos)
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.widget.TextView;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
@@ -56,6 +57,8 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
|
||||
private static final int FADE_OUT_DURATION = 100;
|
||||
private static final int SEARCH_TRANSLATION_X_DP = 18;
|
||||
|
||||
private static final Pattern SPLIT_PATTERN = Pattern.compile("[\\s|\\p{javaSpaceChar}]+");
|
||||
|
||||
@Thunk Launcher mLauncher;
|
||||
@Thunk AlphabeticalAppsList mApps;
|
||||
private AppsGridAdapter mAdapter;
|
||||
@@ -430,23 +433,24 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
if (s.toString().isEmpty()) {
|
||||
String queryText = s.toString();
|
||||
if (queryText.isEmpty()) {
|
||||
mApps.setFilter(null);
|
||||
} else {
|
||||
String formatStr = getResources().getString(R.string.apps_view_no_search_results);
|
||||
mAdapter.setEmptySearchText(String.format(formatStr, s.toString()));
|
||||
mAdapter.setEmptySearchText(String.format(formatStr, queryText));
|
||||
|
||||
final String filterText = s.toString().toLowerCase().replaceAll("\\s+", "");
|
||||
final String queryTextLower = queryText.toLowerCase();
|
||||
mApps.setFilter(new AlphabeticalAppsList.Filter() {
|
||||
@Override
|
||||
public boolean retainApp(AppInfo info, String sectionName) {
|
||||
String title = info.title.toString();
|
||||
if (sectionName.toLowerCase().contains(filterText)) {
|
||||
if (sectionName.toLowerCase().contains(queryTextLower)) {
|
||||
return true;
|
||||
}
|
||||
String[] words = title.toLowerCase().split("\\s+");
|
||||
String title = info.title.toString();
|
||||
String[] words = SPLIT_PATTERN.split(title.toLowerCase());
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
if (words[i].startsWith(filterText)) {
|
||||
if (words[i].startsWith(queryTextLower)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,13 +309,14 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
mFolderName.setHint(sHintText);
|
||||
// Convert to a string here to ensure that no other state associated with the text field
|
||||
// gets saved.
|
||||
String newTitle = mFolderName.getText().toString();
|
||||
CharSequence newTitle = mFolderName.getText();
|
||||
mInfo.setTitle(newTitle);
|
||||
LauncherModel.updateItemInDatabase(mLauncher, mInfo);
|
||||
|
||||
if (commit) {
|
||||
sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
|
||||
String.format(getContext().getString(R.string.folder_renamed), newTitle));
|
||||
String.format(getContext().getString(R.string.folder_renamed),
|
||||
newTitle.toString()));
|
||||
}
|
||||
// In order to clear the focus from the text field, we set the focus on ourself. This
|
||||
// ensures that every time the field is clicked, focus is gained, giving reliable behavior.
|
||||
|
||||
@@ -710,7 +710,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
}
|
||||
|
||||
public void onTitleChanged(CharSequence title) {
|
||||
mFolderName.setText(title.toString());
|
||||
mFolderName.setText(title);
|
||||
setContentDescription(String.format(getContext().getString(R.string.folder_name_format),
|
||||
title));
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class FolderInfo extends ItemInfo {
|
||||
}
|
||||
|
||||
public void setTitle(CharSequence title) {
|
||||
this.title = title;
|
||||
this.title = Utilities.trim(title);
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
listeners.get(i).onTitleChanged(title);
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ public class IconCache {
|
||||
UserHandleCompat user = info == null ? application.user : info.getUser();
|
||||
CacheEntry entry = cacheLocked(application.componentName, info, user,
|
||||
false, useLowResIcon);
|
||||
application.title = entry.title;
|
||||
application.title = Utilities.trim(entry.title);
|
||||
application.iconBitmap = getNonNullIcon(entry, user);
|
||||
application.contentDescription = entry.contentDescription;
|
||||
application.usingLowResIcon = entry.isLowResIcon;
|
||||
@@ -413,7 +413,7 @@ public class IconCache {
|
||||
CacheEntry entry = cacheLocked(application.componentName, null, application.user,
|
||||
false, application.usingLowResIcon);
|
||||
if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) {
|
||||
application.title = entry.title;
|
||||
application.title = Utilities.trim(entry.title);
|
||||
application.iconBitmap = entry.icon;
|
||||
application.contentDescription = entry.contentDescription;
|
||||
application.usingLowResIcon = entry.isLowResIcon;
|
||||
@@ -464,7 +464,7 @@ public class IconCache {
|
||||
UserHandleCompat user, boolean usePkgIcon, boolean useLowResIcon) {
|
||||
CacheEntry entry = cacheLocked(component, info, user, usePkgIcon, useLowResIcon);
|
||||
shortcutInfo.setIcon(getNonNullIcon(entry, user));
|
||||
shortcutInfo.title = entry.title;
|
||||
shortcutInfo.title = Utilities.trim(entry.title);
|
||||
shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user);
|
||||
shortcutInfo.usingLowResIcon = entry.isLowResIcon;
|
||||
}
|
||||
@@ -477,7 +477,7 @@ public class IconCache {
|
||||
PackageItemInfo infoOut) {
|
||||
CacheEntry entry = getEntryForPackageLocked(packageName, user, useLowResIcon);
|
||||
infoOut.iconBitmap = getNonNullIcon(entry, user);
|
||||
infoOut.title = entry.title;
|
||||
infoOut.title = Utilities.trim(entry.title);
|
||||
infoOut.usingLowResIcon = entry.isLowResIcon;
|
||||
infoOut.contentDescription = entry.contentDescription;
|
||||
}
|
||||
@@ -530,7 +530,7 @@ public class IconCache {
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(entry.title) && info != null) {
|
||||
entry.title = info.getLabel().toString();
|
||||
entry.title = info.getLabel();
|
||||
entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ActivityInfo info = pm.getActivityInfo(intent.getComponent(), 0);
|
||||
name = info.loadLabel(pm).toString();
|
||||
name = info.loadLabel(pm);
|
||||
} catch (PackageManager.NameNotFoundException nnfe) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo {
|
||||
|
||||
public String getLabel(PackageManager packageManager) {
|
||||
if (isCustomWidget) {
|
||||
return label.toString().trim();
|
||||
return Utilities.trim(label);
|
||||
}
|
||||
return super.loadLabel(packageManager);
|
||||
}
|
||||
|
||||
@@ -969,7 +969,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
break;
|
||||
}
|
||||
|
||||
folderInfo.title = c.getString(titleIndex);
|
||||
folderInfo.title = Utilities.trim(c.getString(titleIndex));
|
||||
folderInfo.id = id;
|
||||
folderInfo.container = c.getInt(containerIndex);
|
||||
folderInfo.screenId = c.getInt(screenIndex);
|
||||
@@ -2144,7 +2144,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
id = c.getLong(idIndex);
|
||||
FolderInfo folderInfo = findOrMakeFolder(sBgFolders, id);
|
||||
|
||||
folderInfo.title = c.getString(titleIndex);
|
||||
folderInfo.title = Utilities.trim(c.getString(titleIndex));
|
||||
folderInfo.id = id;
|
||||
container = c.getInt(containerIndex);
|
||||
folderInfo.container = container;
|
||||
@@ -3199,7 +3199,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction())
|
||||
&& si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
|
||||
si.updateIcon(mIconCache);
|
||||
si.title = appInfo.title.toString();
|
||||
si.title = Utilities.trim(appInfo.title);
|
||||
si.contentDescription = appInfo.contentDescription;
|
||||
infoUpdated = true;
|
||||
}
|
||||
@@ -3428,18 +3428,17 @@ public class LauncherModel extends BroadcastReceiver
|
||||
if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) {
|
||||
String title = (cursor != null) ? cursor.getString(titleIndex) : null;
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
info.title = title;
|
||||
info.title = Utilities.trim(title);
|
||||
}
|
||||
} else if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) {
|
||||
if (TextUtils.isEmpty(info.title)) {
|
||||
info.title = (cursor != null) ? cursor.getString(titleIndex) : "";
|
||||
info.title = (cursor != null) ? Utilities.trim(cursor.getString(titleIndex)) : "";
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterException("Invalid restoreType " + promiseType);
|
||||
}
|
||||
|
||||
info.contentDescription = mUserManager.getBadgedLabelForUser(
|
||||
info.title.toString(), info.user);
|
||||
info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
|
||||
info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
|
||||
info.promisedIntent = intent;
|
||||
info.status = promiseType;
|
||||
@@ -3501,7 +3500,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
|
||||
// from the db
|
||||
if (TextUtils.isEmpty(info.title) && c != null) {
|
||||
info.title = c.getString(titleIndex);
|
||||
info.title = Utilities.trim(c.getString(titleIndex));
|
||||
}
|
||||
|
||||
// fall back to the class name of the activity
|
||||
@@ -3511,8 +3510,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
|
||||
info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
|
||||
info.user = user;
|
||||
info.contentDescription = mUserManager.getBadgedLabelForUser(
|
||||
info.title.toString(), info.user);
|
||||
info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
|
||||
if (lai != null) {
|
||||
info.flags = AppInfo.initFlags(lai);
|
||||
}
|
||||
@@ -3578,7 +3576,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
|
||||
// TODO: If there's an explicit component and we can't install that, delete it.
|
||||
|
||||
info.title = c.getString(titleIndex);
|
||||
info.title = Utilities.trim(c.getString(titleIndex));
|
||||
|
||||
int iconType = c.getInt(iconTypeIndex);
|
||||
switch (iconType) {
|
||||
@@ -3656,9 +3654,8 @@ public class LauncherModel extends BroadcastReceiver
|
||||
}
|
||||
info.setIcon(icon);
|
||||
|
||||
info.title = name;
|
||||
info.contentDescription = mUserManager.getBadgedLabelForUser(
|
||||
info.title.toString(), info.user);
|
||||
info.title = Utilities.trim(name);
|
||||
info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
|
||||
info.intent = intent;
|
||||
info.customIcon = customIcon;
|
||||
info.iconResource = iconResource;
|
||||
@@ -3699,16 +3696,16 @@ public class LauncherModel extends BroadcastReceiver
|
||||
labelA = mLabelCache.get(a);
|
||||
} else {
|
||||
labelA = (a instanceof LauncherAppWidgetProviderInfo)
|
||||
? mManager.loadLabel((LauncherAppWidgetProviderInfo) a)
|
||||
: ((ResolveInfo) a).loadLabel(mPackageManager).toString().trim();
|
||||
? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) a))
|
||||
: Utilities.trim(((ResolveInfo) a).loadLabel(mPackageManager));
|
||||
mLabelCache.put(a, labelA);
|
||||
}
|
||||
if (mLabelCache.containsKey(b)) {
|
||||
labelB = mLabelCache.get(b);
|
||||
} else {
|
||||
labelB = (b instanceof LauncherAppWidgetProviderInfo)
|
||||
? mManager.loadLabel((LauncherAppWidgetProviderInfo) b)
|
||||
: ((ResolveInfo) b).loadLabel(mPackageManager).toString().trim();
|
||||
? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) b))
|
||||
: Utilities.trim(((ResolveInfo) b).loadLabel(mPackageManager));
|
||||
mLabelCache.put(b, labelB);
|
||||
}
|
||||
return mCollator.compare(labelA, labelB);
|
||||
|
||||
@@ -153,7 +153,7 @@ public class ShortcutInfo extends ItemInfo {
|
||||
Bitmap icon, UserHandleCompat user) {
|
||||
this();
|
||||
this.intent = intent;
|
||||
this.title = title;
|
||||
this.title = Utilities.trim(title);
|
||||
this.contentDescription = contentDescription;
|
||||
mIcon = icon;
|
||||
this.user = user;
|
||||
@@ -161,7 +161,7 @@ public class ShortcutInfo extends ItemInfo {
|
||||
|
||||
public ShortcutInfo(Context context, ShortcutInfo info) {
|
||||
super(info);
|
||||
title = info.title.toString();
|
||||
title = Utilities.trim(info.title);
|
||||
intent = new Intent(info.intent);
|
||||
if (info.iconResource != null) {
|
||||
iconResource = new Intent.ShortcutIconResource();
|
||||
@@ -179,7 +179,7 @@ public class ShortcutInfo extends ItemInfo {
|
||||
/** TODO: Remove this. It's only called by ApplicationInfo.makeShortcut. */
|
||||
public ShortcutInfo(AppInfo info) {
|
||||
super(info);
|
||||
title = info.title.toString();
|
||||
title = Utilities.trim(info.title);
|
||||
intent = new Intent(info.intent);
|
||||
customIcon = false;
|
||||
flags = info.flags;
|
||||
@@ -281,7 +281,7 @@ public class ShortcutInfo extends ItemInfo {
|
||||
public static ShortcutInfo fromActivityInfo(LauncherActivityInfoCompat info, Context context) {
|
||||
final ShortcutInfo shortcut = new ShortcutInfo();
|
||||
shortcut.user = info.getUser();
|
||||
shortcut.title = info.getLabel().toString();
|
||||
shortcut.title = Utilities.trim(info.getLabel());
|
||||
shortcut.contentDescription = UserManagerCompat.getInstance(context)
|
||||
.getBadgedLabelForUser(info.getLabel(), info.getUser());
|
||||
shortcut.customIcon = false;
|
||||
|
||||
@@ -54,6 +54,8 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Various utilities shared amongst the Launcher's classes.
|
||||
@@ -67,6 +69,9 @@ public final class Utilities {
|
||||
private static final Rect sOldBounds = new Rect();
|
||||
private static final Canvas sCanvas = new Canvas();
|
||||
|
||||
private static final Pattern sTrimPattern =
|
||||
Pattern.compile("^[\\s|\\p{javaSpaceChar}]*(.*)[\\s|\\p{javaSpaceChar}]*$");
|
||||
|
||||
static {
|
||||
sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
|
||||
Paint.FILTER_BITMAP_FLAG));
|
||||
@@ -616,4 +621,14 @@ public final class Utilities {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the string, removing all whitespace at the beginning and end of the string.
|
||||
* Non-breaking whitespaces are also removed.
|
||||
*/
|
||||
public static String trim(CharSequence s) {
|
||||
// Just strip any sequence of whitespace or java space characters from the beginning and end
|
||||
Matcher m = sTrimPattern.matcher(s);
|
||||
return m.replaceAll("$1");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ public class WorkspaceAccessibilityHelper extends DragAndDropAccessibilityDelega
|
||||
if (info instanceof ShortcutInfo) {
|
||||
return mContext.getString(R.string.create_folder_with, info.title);
|
||||
} else if (info instanceof FolderInfo) {
|
||||
if (TextUtils.isEmpty(info.title.toString().trim())) {
|
||||
if (TextUtils.isEmpty(info.title)) {
|
||||
// Find the first item in the folder.
|
||||
FolderInfo folder = (FolderInfo) info;
|
||||
ShortcutInfo firstItem = null;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.android.launcher3.compat;
|
||||
|
||||
import android.content.Context;
|
||||
import com.android.launcher3.Utilities;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -102,10 +103,11 @@ public class AlphabeticIndexCompat extends BaseAlphabeticIndex {
|
||||
/**
|
||||
* Computes the section name for an given string {@param s}.
|
||||
*/
|
||||
public String computeSectionName(String s) {
|
||||
public String computeSectionName(CharSequence cs) {
|
||||
String s = Utilities.trim(cs);
|
||||
String sectionName = getBucketLabel(getBucketIndex(s));
|
||||
if (sectionName.trim().isEmpty() && s.length() > 0) {
|
||||
boolean startsWithDigit = Character.isDigit(Character.codePointAt(s.trim(), 0));
|
||||
if (Utilities.trim(sectionName).isEmpty() && s.length() > 0) {
|
||||
boolean startsWithDigit = Character.isDigit(s.codePointAt(0));
|
||||
if (startsWithDigit) {
|
||||
// Digit section
|
||||
return "#";
|
||||
|
||||
@@ -46,7 +46,7 @@ class AppWidgetManagerCompatV16 extends AppWidgetManagerCompat {
|
||||
|
||||
@Override
|
||||
public String loadLabel(LauncherAppWidgetProviderInfo info) {
|
||||
return info.label.trim();
|
||||
return Utilities.trim(info.label);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -49,7 +49,7 @@ public class PackageItemInfo extends ItemInfo {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PackageItemInfo(title=" + title.toString() + " id=" + this.id
|
||||
return "PackageItemInfo(title=" + title + " id=" + this.id
|
||||
+ " type=" + this.itemType + " container=" + this.container
|
||||
+ " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY
|
||||
+ " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos)
|
||||
|
||||
@@ -222,10 +222,9 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
||||
* Helper method to get the string info of the tag.
|
||||
*/
|
||||
private String getTagToString() {
|
||||
if (getTag() instanceof PendingAddWidgetInfo) {
|
||||
return ((PendingAddWidgetInfo)getTag()).toString();
|
||||
} else if (getTag() instanceof PendingAddShortcutInfo) {
|
||||
return ((PendingAddShortcutInfo)getTag()).toString();
|
||||
if (getTag() instanceof PendingAddWidgetInfo ||
|
||||
getTag() instanceof PendingAddShortcutInfo) {
|
||||
return getTag().toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user