Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 707b1181 authored by Steven Ng's avatar Steven Ng
Browse files

Use ICU to format plural strings

Test: manual
Fix: 199230208
Change-Id: I0b6fe9f8bb134a1479117c832575c63da2a07794
parent 8b30227f
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -67,17 +67,15 @@
         button in a dialog. [CHAR_LIMIT=none] -->
    <string name="added_to_home_screen_accessibility_text"><xliff:g id="widget_name" example="Calendar month view">%1$s</xliff:g> widget added to home screen</string>
    <!-- Label for showing the number of widgets an app has in the full widgets picker.
         [CHAR_LIMIT=25] -->
    <plurals name="widgets_count">
        <item quantity="one"><xliff:g id="widgets_count" example="1">%1$d</xliff:g> widget</item>
        <item quantity="other"><xliff:g id="widgets_count" example="2">%1$d</xliff:g> widgets</item>
    </plurals>
         [CHAR_LIMIT=25][ICU SYNTAX] -->
    <string name="widgets_count">
        {count, plural, =1{# widget} other{# widgets}}
    </string>
    <!-- Label for showing the number of shortcut an app has in the full widgets picker.
         [CHAR_LIMIT=25] -->
    <plurals name="shortcuts_count">
        <item quantity="one"><xliff:g id="shortcuts_count" example="1">%1$d</xliff:g> shortcut</item>
        <item quantity="other"><xliff:g id="shortcuts_count" example="2">%1$d</xliff:g> shortcuts</item>
    </plurals>
         [CHAR_LIMIT=25][ICU SYNTAX] -->
    <string name="shortcuts_count">
        {count, plural, =1{# shortcut} other{# shortcuts}}
    </string>
    <!-- Label for showing both the number of widgets and shortcuts an app has in the full widgets
         picker. [CHAR_LIMIT=50] -->
    <string name="widgets_and_shortcuts_count"><xliff:g id="widgets_count" example="5 widgets">%1$s</xliff:g>, <xliff:g id="shortcuts_count" example="1 shortcut">%2$s</xliff:g></string>
@@ -212,11 +210,13 @@
    <!-- Accessibility -->
    <!-- The format string for when an app is temporarily disabled. -->
    <string name="disabled_app_label">Disabled <xliff:g id="app_name" example="Messenger">%1$s</xliff:g></string>
    <!-- The format string for when an app has a notification dot (meaning it has associated notifications). -->
    <plurals name="dotted_app_label">
        <item quantity="one"><xliff:g id="app_name" example="Messenger">%1$s</xliff:g>, has <xliff:g id="notification_count" example="1">%2$d</xliff:g> notification</item>
        <item quantity="other"><xliff:g id="app_name" example="Messenger">%1$s</xliff:g>, has <xliff:g id="notification_count" example="3">%2$d</xliff:g> notifications</item>
    </plurals>
    <!-- The format string for when an app has a notification dot (meaning it has associated notifications). [ICU_FORMAT]-->
    <string name="dotted_app_label">
        {count, plural, offset:1
            =1      {{app_name} has # notification}
            other   {{app_name} has # notifications}
        }
    </string>
    <skip />

    <!-- The format string for default page scroll text [CHAR_LIMIT=none] -->
+15 −2
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.icu.text.MessageFormat;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.Property;
@@ -68,6 +69,8 @@ import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.IconLabelDotView;

import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Locale;

/**
 * TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
@@ -695,8 +698,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
                            itemInfo.contentDescription));
                } else if (hasDot()) {
                    int count = mDotInfo.getNotificationCount();
                    setContentDescription(getContext().getResources().getQuantityString(
                            R.plurals.dotted_app_label, count, itemInfo.contentDescription, count));
                    setContentDescription(
                            getAppLabelPluralString(itemInfo.contentDescription.toString(), count));
                } else {
                    setContentDescription(itemInfo.contentDescription);
                }
@@ -938,4 +941,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
            setCompoundDrawables(null, newIcon, null, null);
        }
    }

    private String getAppLabelPluralString(String appName, int notificationCount) {
        MessageFormat icuCountFormat = new MessageFormat(
                getResources().getString(R.string.dotted_app_label),
                Locale.getDefault());
        HashMap<String, Object> args = new HashMap();
        args.put("app_name", appName);
        args.put("count", notificationCount);
        return icuCountFormat.format(args);
    }
}
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.launcher3.util;

import android.content.Context;
import android.icu.text.MessageFormat;

import androidx.annotation.StringRes;

import java.util.HashMap;
import java.util.Locale;

/** A helper class to format common ICU plural strings. */
public class PluralMessageFormat {

    /**
     * Returns a plural string from a ICU format message template, which takes "count" as an
     * argument.
     *
     * <p>An example of ICU format message template provided by {@code stringId}:
     * {count, plural, =1{# widget} other{# widgets}}
     */
    public static final String getIcuPluralString(Context context, @StringRes int stringId,
            int count) {
        MessageFormat icuCountFormat = new MessageFormat(
                context.getResources().getString(stringId),
                Locale.getDefault());
        HashMap<String, Object> args = new HashMap();
        args.put("count", count);
        return icuCountFormat.format(args);
    }
}
+9 −8
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.launcher3.icons.PlaceHolderIconDrawable;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.util.PluralMessageFormat;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
@@ -217,18 +218,18 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd

        String subtitle;
        if (entry.widgetsCount > 0 && entry.shortcutsCount > 0) {
            String widgetsCount = resources.getQuantityString(R.plurals.widgets_count,
                    entry.widgetsCount, entry.widgetsCount);
            String shortcutsCount = resources.getQuantityString(R.plurals.shortcuts_count,
                    entry.shortcutsCount, entry.shortcutsCount);
            String widgetsCount = PluralMessageFormat.getIcuPluralString(getContext(),
                    R.string.widgets_count, entry.widgetsCount);
            String shortcutsCount = PluralMessageFormat.getIcuPluralString(getContext(),
                    R.string.shortcuts_count, entry.shortcutsCount);
            subtitle = resources.getString(R.string.widgets_and_shortcuts_count, widgetsCount,
                    shortcutsCount);
        } else if (entry.widgetsCount > 0) {
            subtitle = resources.getQuantityString(R.plurals.widgets_count,
                    entry.widgetsCount, entry.widgetsCount);
            subtitle = PluralMessageFormat.getIcuPluralString(getContext(),
                    R.string.widgets_count, entry.widgetsCount);
        } else {
            subtitle = resources.getQuantityString(R.plurals.shortcuts_count,
                    entry.shortcutsCount, entry.shortcutsCount);
            subtitle = PluralMessageFormat.getIcuPluralString(getContext(),
                    R.string.shortcuts_count, entry.shortcutsCount);
        }
        mSubtitle.setText(subtitle);
        mSubtitle.setVisibility(VISIBLE);