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 */ 16 package com.android.documentsui.ui; 17 18 import androidx.annotation.PluralsRes; 19 import android.content.Context; 20 import android.text.BidiFormatter; 21 import android.net.Uri; 22 import android.text.Html; 23 24 import com.android.documentsui.OperationDialogFragment.DialogType; 25 import com.android.documentsui.R; 26 import com.android.documentsui.base.DocumentInfo; 27 import com.android.documentsui.base.Shared; 28 import com.android.documentsui.services.FileOperationService; 29 import com.android.documentsui.services.FileOperationService.OpType; 30 import com.android.documentsui.OperationDialogFragment.DialogType; 31 32 import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_FAILURE; 33 import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_CONVERTED; 34 35 import java.util.List; 36 37 public class MessageBuilder { 38 39 private Context mContext; 40 MessageBuilder(Context context)41 public MessageBuilder(Context context) { 42 mContext = context; 43 } 44 generateDeleteMessage(List<DocumentInfo> docs)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 generateListMessage( @ialogType int dialogType, @OpType int operationType, List<DocumentInfo> docs, List<Uri> uris)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("• " + Html.escapeHtml(BidiFormatter.getInstance().unicodeWrap( 121 documentInfo.displayName)) + "<br>"); 122 } 123 if (uris != null) { 124 for (Uri uri : uris) { 125 list.append("• " + 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 */ getQuantityString(@luralsRes int stringId, int quantity)138 public String getQuantityString(@PluralsRes int stringId, int quantity) { 139 return Shared.getQuantityString(mContext, stringId, quantity); 140 } 141 } 142