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