1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.documentsui.ui;
17
18import android.annotation.PluralsRes;
19import android.content.Context;
20import android.text.BidiFormatter;
21import android.net.Uri;
22import android.text.Html;
23
24import com.android.documentsui.OperationDialogFragment.DialogType;
25import com.android.documentsui.R;
26import com.android.documentsui.base.DocumentInfo;
27import com.android.documentsui.base.Shared;
28import com.android.documentsui.services.FileOperationService;
29import com.android.documentsui.services.FileOperationService.OpType;
30import com.android.documentsui.OperationDialogFragment.DialogType;
31
32import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_FAILURE;
33import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_CONVERTED;
34
35import java.util.List;
36
37public class MessageBuilder {
38
39    private Context mContext;
40
41    public MessageBuilder(Context context) {
42        mContext = context;
43    }
44
45    public String generateDeleteMessage(List<DocumentInfo> docs) {
46        String message;
47        int dirsCount = 0;
48
49        for (DocumentInfo doc : docs) {
50            if (doc.isDirectory()) {
51                ++dirsCount;
52            }
53        }
54
55        if (docs.size() == 1) {
56            // Deleteing 1 file xor 1 folder in cwd
57
58            // Address b/28772371, where including user strings in message can result in
59            // broken bidirectional support.
60            String displayName = BidiFormatter.getInstance().unicodeWrap(docs.get(0).displayName);
61            message = dirsCount == 0
62                    ? mContext.getString(R.string.delete_filename_confirmation_message,
63                            displayName)
64                    : mContext.getString(R.string.delete_foldername_confirmation_message,
65                            displayName);
66        } else if (dirsCount == 0) {
67            // Deleting only files in cwd
68            message = Shared.getQuantityString(mContext,
69                    R.plurals.delete_files_confirmation_message, docs.size());
70        } else if (dirsCount == docs.size()) {
71            // Deleting only folders in cwd
72            message = Shared.getQuantityString(mContext,
73                    R.plurals.delete_folders_confirmation_message, docs.size());
74        } else {
75            // Deleting mixed items (files and folders) in cwd
76            message = Shared.getQuantityString(mContext,
77                    R.plurals.delete_items_confirmation_message, docs.size());
78        }
79        return message;
80    }
81
82    public String generateListMessage(
83            @DialogType int dialogType, @OpType int operationType, List<DocumentInfo> docs,
84            List<Uri> uris) {
85        int resourceId;
86
87        switch (dialogType) {
88            case DIALOG_TYPE_CONVERTED:
89                resourceId = R.plurals.copy_converted_warning_content;
90                break;
91
92            case DIALOG_TYPE_FAILURE:
93                switch (operationType) {
94                    case FileOperationService.OPERATION_COPY:
95                        resourceId = R.plurals.copy_failure_alert_content;
96                        break;
97                    case FileOperationService.OPERATION_COMPRESS:
98                        resourceId = R.plurals.compress_failure_alert_content;
99                        break;
100                    case FileOperationService.OPERATION_EXTRACT:
101                        resourceId = R.plurals.extract_failure_alert_content;
102                        break;
103                    case FileOperationService.OPERATION_DELETE:
104                        resourceId = R.plurals.delete_failure_alert_content;
105                        break;
106                    case FileOperationService.OPERATION_MOVE:
107                        resourceId = R.plurals.move_failure_alert_content;
108                        break;
109                    default:
110                        throw new UnsupportedOperationException();
111                }
112                break;
113
114            default:
115                throw new UnsupportedOperationException();
116        }
117
118        final StringBuilder list = new StringBuilder("<p>");
119        for (DocumentInfo documentInfo : docs) {
120            list.append("&#8226; " + Html.escapeHtml(BidiFormatter.getInstance().unicodeWrap(
121                    documentInfo.displayName)) + "<br>");
122        }
123        if (uris != null) {
124            for (Uri uri : uris) {
125                list.append("&#8226; " + BidiFormatter.getInstance().unicodeWrap(uri.toSafeString()) +
126                        "<br>");
127            }
128        }
129        list.append("</p>");
130
131        final int totalItems = docs.size() + (uris != null ? uris.size() : 0);
132        return mContext.getResources().getQuantityString(resourceId, totalItems, list.toString());
133    }
134
135    /**
136     * Generates a formatted quantity string.
137     */
138    public String getQuantityString(@PluralsRes int stringId, int quantity) {
139        return Shared.getQuantityString(mContext, stringId, quantity);
140    }
141}
142