Remove actionbarsherlock , replace it with Android Support Library (v7)
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / ErrorsWhileCopyingHandlerActivity.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author David A. Velasco
5 * Copyright (C) 2015 ownCloud Inc.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2,
9 * as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 package com.owncloud.android.ui.activity;
22
23 import java.io.File;
24 import java.util.ArrayList;
25
26 import android.accounts.Account;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.os.AsyncTask;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.support.v4.app.DialogFragment;
33 import android.support.v7.app.AppCompatActivity;
34 import android.text.method.ScrollingMovementMethod;
35 import android.view.LayoutInflater;
36 import android.view.View;
37 import android.view.View.OnClickListener;
38 import android.view.ViewGroup;
39 import android.widget.ArrayAdapter;
40 import android.widget.Button;
41 import android.widget.ListView;
42 import android.widget.TextView;
43 import android.widget.Toast;
44
45 import com.owncloud.android.R;
46 import com.owncloud.android.datamodel.FileDataStorageManager;
47 import com.owncloud.android.datamodel.OCFile;
48 import com.owncloud.android.lib.common.utils.Log_OC;
49
50 import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
51 import com.owncloud.android.utils.FileStorageUtils;
52
53
54
55 /**
56 * Activity reporting errors occurred when local files uploaded to an ownCloud account with an app
57 * in version under 1.3.16 where being copied to the ownCloud local folder.
58 *
59 * Allows the user move the files to the ownCloud local folder. let them unlinked to the remote
60 * files.
61 *
62 * Shown when the error notification summarizing the list of errors is clicked by the user.
63 */
64 public class ErrorsWhileCopyingHandlerActivity extends AppCompatActivity
65 implements OnClickListener {
66
67 private static final String TAG = ErrorsWhileCopyingHandlerActivity.class.getSimpleName();
68
69 public static final String EXTRA_ACCOUNT =
70 ErrorsWhileCopyingHandlerActivity.class.getCanonicalName() + ".EXTRA_ACCOUNT";
71 public static final String EXTRA_LOCAL_PATHS =
72 ErrorsWhileCopyingHandlerActivity.class.getCanonicalName() + ".EXTRA_LOCAL_PATHS";
73 public static final String EXTRA_REMOTE_PATHS =
74 ErrorsWhileCopyingHandlerActivity.class.getCanonicalName() + ".EXTRA_REMOTE_PATHS";
75
76 private static final String WAIT_DIALOG_TAG = "WAIT_DIALOG";
77
78 protected Account mAccount;
79 protected FileDataStorageManager mStorageManager;
80 protected ArrayList<String> mLocalPaths;
81 protected ArrayList<String> mRemotePaths;
82 protected ArrayAdapter<String> mAdapter;
83 protected Handler mHandler;
84 private DialogFragment mCurrentDialog;
85
86 /**
87 * {@link}
88 */
89 @Override
90 protected void onCreate(Bundle savedInstanceState) {
91 super.onCreate(savedInstanceState);
92
93 /// read extra parameters in intent
94 Intent intent = getIntent();
95 mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT);
96 mRemotePaths = intent.getStringArrayListExtra(EXTRA_REMOTE_PATHS);
97 mLocalPaths = intent.getStringArrayListExtra(EXTRA_LOCAL_PATHS);
98 mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
99 mHandler = new Handler();
100 if (mCurrentDialog != null) {
101 mCurrentDialog.dismiss();
102 mCurrentDialog = null;
103 }
104
105 /// load generic layout
106 setContentView(R.layout.generic_explanation);
107
108 /// customize text message
109 TextView textView = (TextView) findViewById(R.id.message);
110 String appName = getString(R.string.app_name);
111 String message = String.format(getString(R.string.sync_foreign_files_forgotten_explanation),
112 appName, appName, appName, appName, mAccount.name);
113 textView.setText(message);
114 textView.setMovementMethod(new ScrollingMovementMethod());
115
116 /// load the list of local and remote files that failed
117 ListView listView = (ListView) findViewById(R.id.list);
118 if (mLocalPaths != null && mLocalPaths.size() > 0) {
119 mAdapter = new ErrorsWhileCopyingListAdapter();
120 listView.setAdapter(mAdapter);
121 } else {
122 listView.setVisibility(View.GONE);
123 mAdapter = null;
124 }
125
126 /// customize buttons
127 Button cancelBtn = (Button) findViewById(R.id.cancel);
128 Button okBtn = (Button) findViewById(R.id.ok);
129
130 okBtn.setText(R.string.foreign_files_move);
131 cancelBtn.setOnClickListener(this);
132 okBtn.setOnClickListener(this);
133 }
134
135
136 /**
137 * Customized adapter, showing the local files as main text in two-lines list item and the
138 * remote files as the secondary text.
139 */
140 public class ErrorsWhileCopyingListAdapter extends ArrayAdapter<String> {
141
142 ErrorsWhileCopyingListAdapter() {
143 super(ErrorsWhileCopyingHandlerActivity.this, android.R.layout.two_line_list_item,
144 android.R.id.text1, mLocalPaths);
145 }
146
147 @Override
148 public boolean isEnabled(int position) {
149 return false;
150 }
151
152 /**
153 * {@inheritDoc}
154 */
155 @Override
156 public View getView (int position, View convertView, ViewGroup parent) {
157 View view = convertView;
158 if (view == null) {
159 LayoutInflater vi = (LayoutInflater) getSystemService(
160 Context.LAYOUT_INFLATER_SERVICE);
161 view = vi.inflate(android.R.layout.two_line_list_item, null);
162 }
163 if (view != null) {
164 String localPath = getItem(position);
165 if (localPath != null) {
166 TextView text1 = (TextView) view.findViewById(android.R.id.text1);
167 if (text1 != null) {
168 text1.setText(String.format(getString(R.string.foreign_files_local_text), localPath));
169 }
170 }
171 if (mRemotePaths != null && mRemotePaths.size() > 0 && position >= 0 &&
172 position < mRemotePaths.size()) {
173 TextView text2 = (TextView) view.findViewById(android.R.id.text2);
174 String remotePath = mRemotePaths.get(position);
175 if (text2 != null && remotePath != null) {
176 text2.setText(String.format(getString(R.string.foreign_files_remote_text), remotePath));
177 }
178 }
179 }
180 return view;
181 }
182 }
183
184
185 /**
186 * Listener method to perform the MOVE / CANCEL action available in this activity.
187 *
188 * @param v Clicked view (button MOVE or CANCEL)
189 */
190 @Override
191 public void onClick(View v) {
192 if (v.getId() == R.id.ok) {
193 /// perform movement operation in background thread
194 Log_OC.d(TAG, "Clicked MOVE, start movement");
195 new MoveFilesTask().execute();
196
197 } else if (v.getId() == R.id.cancel) {
198 /// just finish
199 Log_OC.d(TAG, "Clicked CANCEL, bye");
200 finish();
201
202 } else {
203 Log_OC.e(TAG, "Clicked phantom button, id: " + v.getId());
204 }
205 }
206
207
208 /**
209 * Asynchronous task performing the move of all the local files to the ownCloud folder.
210 */
211 private class MoveFilesTask extends AsyncTask<Void, Void, Boolean> {
212
213 /**
214 * Updates the UI before trying the movement
215 */
216 @Override
217 protected void onPreExecute () {
218 /// progress dialog and disable 'Move' button
219 mCurrentDialog = IndeterminateProgressDialog.newInstance(R.string.wait_a_moment, false);
220 mCurrentDialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);
221 findViewById(R.id.ok).setEnabled(false);
222 }
223
224
225 /**
226 * Performs the movement
227 *
228 * @return 'False' when the movement of any file fails.
229 */
230 @Override
231 protected Boolean doInBackground(Void... params) {
232 while (!mLocalPaths.isEmpty()) {
233 String currentPath = mLocalPaths.get(0);
234 File currentFile = new File(currentPath);
235 String expectedPath = FileStorageUtils.getSavePath(mAccount.name) + mRemotePaths.get(0);
236 File expectedFile = new File(expectedPath);
237
238 if (expectedFile.equals(currentFile) || currentFile.renameTo(expectedFile)) {
239 // SUCCESS
240 OCFile file = mStorageManager.getFileByPath(mRemotePaths.get(0));
241 file.setStoragePath(expectedPath);
242 mStorageManager.saveFile(file);
243 mRemotePaths.remove(0);
244 mLocalPaths.remove(0);
245
246 } else {
247 // FAIL
248 return false;
249 }
250 }
251 return true;
252 }
253
254 /**
255 * Updates the activity UI after the movement of local files is tried.
256 *
257 * If the movement was successful for all the files, finishes the activity immediately.
258 *
259 * In other case, the list of remaining files is still available to retry the movement.
260 *
261 * @param result 'True' when the movement was successful.
262 */
263 @Override
264 protected void onPostExecute(Boolean result) {
265 mAdapter.notifyDataSetChanged();
266 mCurrentDialog.dismiss();
267 mCurrentDialog = null;
268 findViewById(R.id.ok).setEnabled(true);
269
270 if (result) {
271 // nothing else to do in this activity
272 Toast t = Toast.makeText(ErrorsWhileCopyingHandlerActivity.this,
273 getString(R.string.foreign_files_success), Toast.LENGTH_LONG);
274 t.show();
275 finish();
276
277 } else {
278 Toast t = Toast.makeText(ErrorsWhileCopyingHandlerActivity.this,
279 getString(R.string.foreign_files_fail), Toast.LENGTH_LONG);
280 t.show();
281 }
282 }
283 }
284
285 }