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