12fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki/* 22fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Copyright (C) 2011 The Android Open Source Project 32fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * 42fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 52fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * you may not use this file except in compliance with the License. 62fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * You may obtain a copy of the License at 72fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * 82fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 92fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * 102fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Unless required by applicable law or agreed to in writing, software 112fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 122fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * See the License for the specific language governing permissions and 142fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * limitations under the License. 152fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki */ 162fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 172fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onukipackage com.android.email.activity; 182fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.R; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 212fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onukiimport android.app.Activity; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.Fragment; 232fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onukiimport android.content.Context; 242fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onukiimport android.content.res.Resources; 252fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onukiimport android.view.View; 262fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 272fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onukipublic class UiUtilities { 282fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki private UiUtilities() { 292fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 302fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 312fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki /** 322fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Formats the given size as a String in bytes, kB, MB or GB. Ex: 12,315,000 = 11 MB 332fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki */ 342fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki public static String formatSize(Context context, long size) { 352fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki final Resources res = context.getResources(); 362fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki final long KB = 1024; 372fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki final long MB = (KB * 1024); 382fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki final long GB = (MB * 1024); 392fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 402fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki int resId; 412fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki int value; 422fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 432fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki if (size < KB) { 442fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki resId = R.plurals.message_view_attachment_bytes; 452fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki value = (int) size; 462fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } else if (size < MB) { 472fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki resId = R.plurals.message_view_attachment_kilobytes; 482fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki value = (int) (size / KB); 492fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } else if (size < GB) { 502fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki resId = R.plurals.message_view_attachment_megabytes; 512fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki value = (int) (size / MB); 522fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } else { 532fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki resId = R.plurals.message_view_attachment_gigabytes; 542fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki value = (int) (size / GB); 552fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 562fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki return res.getQuantityString(resId, value, value); 572fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 582fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 592fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki public static String getMessageCountForUi(Context context, int count, 602fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki boolean replaceZeroWithBlank) { 612fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki if (replaceZeroWithBlank && (count == 0)) { 622fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki return ""; 632fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } else if (count > 999) { 642fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki return context.getString(R.string.more_than_999); 652fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } else { 662fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki return Integer.toString(count); 672fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 682fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 692fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 70c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki /** Generics version of {@link Activity#findViewById} */ 71c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki @SuppressWarnings("unchecked") 72c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki public static <T extends View> T getViewOrNull(Activity parent, int viewId) { 73c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki return (T) parent.findViewById(viewId); 74c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki } 75c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki 76c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki /** Generics version of {@link View#findViewById} */ 77c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki @SuppressWarnings("unchecked") 78c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki public static <T extends View> T getViewOrNull(View parent, int viewId) { 79c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki return (T) parent.findViewById(viewId); 80c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki } 81c0491ed1952633103732ae90bb26cf533304bcc3Makoto Onuki 822fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki /** 832fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Same as {@link Activity#findViewById}, but crashes if there's no view. 842fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki */ 85256652050c8c047d1879621805f028454e83b677Ben Komalo @SuppressWarnings("unchecked") 86256652050c8c047d1879621805f028454e83b677Ben Komalo public static <T extends View> T getView(Activity parent, int viewId) { 87256652050c8c047d1879621805f028454e83b677Ben Komalo return (T) checkView(parent.findViewById(viewId)); 882fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 892fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 902fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki /** 912fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Same as {@link View#findViewById}, but crashes if there's no view. 922fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki */ 93256652050c8c047d1879621805f028454e83b677Ben Komalo @SuppressWarnings("unchecked") 94256652050c8c047d1879621805f028454e83b677Ben Komalo public static <T extends View> T getView(View parent, int viewId) { 95256652050c8c047d1879621805f028454e83b677Ben Komalo return (T) checkView(parent.findViewById(viewId)); 962fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 972fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 982fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki private static View checkView(View v) { 992fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki if (v == null) { 1002fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki throw new IllegalArgumentException("View doesn't exist"); 1012fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 1022fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki return v; 1032fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 1042fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 1052fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki /** 1062fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Same as {@link View#setVisibility(int)}, but doesn't crash even if {@code view} is null. 1072fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki */ 1082fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki public static void setVisibilitySafe(View v, int visibility) { 1092fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki if (v != null) { 1102fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki v.setVisibility(visibility); 1112fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 1122fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 1132fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 1142fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki /** 1152fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Same as {@link View#setVisibility(int)}, but doesn't crash even if {@code view} is null. 1162fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki */ 1172fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki public static void setVisibilitySafe(Activity parent, int viewId, int visibility) { 1182fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki setVisibilitySafe(parent.findViewById(viewId), visibility); 1192fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 1202fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki 1212fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki /** 1222fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki * Same as {@link View#setVisibility(int)}, but doesn't crash even if {@code view} is null. 1232fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki */ 1242fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki public static void setVisibilitySafe(View parent, int viewId, int visibility) { 1252fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki setVisibilitySafe(parent.findViewById(viewId), visibility); 1262fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki } 1273d9b8e76f0a396370a5c0be99a34bf7c24bd20ddMakoto Onuki 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Used by an {@link Fragment} to install itself to the host activity. 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @see FragmentInstallable 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static void installFragment(Fragment fragment) { 134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final Activity a = fragment.getActivity(); 135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (a instanceof FragmentInstallable) { 136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ((FragmentInstallable) a).onInstallFragment(fragment); 137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Used by an {@link Fragment} to uninstall itself from the host activity. 142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @see FragmentInstallable 144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static void uninstallFragment(Fragment fragment) { 146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final Activity a = fragment.getActivity(); 147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (a instanceof FragmentInstallable) { 148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ((FragmentInstallable) a).onUninstallFragment(fragment); 149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 152347ae23b6932fe994b03909bf90854888c438517Makoto Onuki private static int sDebugForcedPaneMode = 0; 153347ae23b6932fe994b03909bf90854888c438517Makoto Onuki 154347ae23b6932fe994b03909bf90854888c438517Makoto Onuki /** 155347ae23b6932fe994b03909bf90854888c438517Makoto Onuki * Force 1-pane UI or 2-pane UI. 156347ae23b6932fe994b03909bf90854888c438517Makoto Onuki * 157347ae23b6932fe994b03909bf90854888c438517Makoto Onuki * @param paneMode Set 1 if 1-pane UI should be used. Set 2 if 2-pane UI should be used. 158347ae23b6932fe994b03909bf90854888c438517Makoto Onuki * Set 0 to use the default UI. 159347ae23b6932fe994b03909bf90854888c438517Makoto Onuki */ 160347ae23b6932fe994b03909bf90854888c438517Makoto Onuki static void setDebugPaneMode(int paneMode) { 161347ae23b6932fe994b03909bf90854888c438517Makoto Onuki sDebugForcedPaneMode = paneMode; 162347ae23b6932fe994b03909bf90854888c438517Makoto Onuki } 163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return {@code true} if 2-pane UI should be used. {@code false} otherwise. 166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static boolean useTwoPane(Context context) { 168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (sDebugForcedPaneMode == 1) { 169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return false; 170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (sDebugForcedPaneMode == 2) { 172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return context.getResources().getBoolean(R.bool.use_two_pane); 175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Return whether to show search results in a split pane. 179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static boolean showTwoPaneSearchResults(Context context) { 181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return context.getResources().getBoolean(R.bool.show_two_pane_search_result); 182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1832fbb3db5d86210d03175ce77ff08c989a96c5864Makoto Onuki} 184