Merge remote-tracking branch 'upstream/develop' into us4_view_text_files
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / preview / PreviewTextFragment.java
1 package com.owncloud.android.ui.preview;
2
3 import android.accounts.Account;
4 import android.os.AsyncTask;
5 import android.os.Bundle;
6 import android.support.v4.app.Fragment;
7 import android.support.v4.app.FragmentManager;
8 import android.support.v4.app.FragmentTransaction;
9 import android.view.LayoutInflater;
10 import android.view.View;
11 import android.view.ViewGroup;
12 import android.widget.ScrollView;
13 import android.widget.TextView;
14
15 import com.actionbarsherlock.view.Menu;
16 import com.actionbarsherlock.view.MenuInflater;
17 import com.actionbarsherlock.view.MenuItem;
18 import com.owncloud.android.R;
19 import com.owncloud.android.datamodel.OCFile;
20 import com.owncloud.android.files.FileMenuFilter;
21 import com.owncloud.android.lib.common.utils.Log_OC;
22 import com.owncloud.android.ui.activity.FileDisplayActivity;
23 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
24 import com.owncloud.android.ui.dialog.LoadingDialog;
25 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
26 import com.owncloud.android.ui.fragment.FileFragment;
27
28 import java.io.BufferedWriter;
29 import java.io.FileInputStream;
30 import java.io.IOException;
31 import java.io.StringWriter;
32 import java.util.Scanner;
33
34 public class PreviewTextFragment extends FileFragment {
35 private static final String EXTRA_FILE = "FILE";
36 private static final String EXTRA_ACCOUNT = "ACCOUNT";
37 private static final String TAG = PreviewTextFragment.class.getSimpleName();
38
39 private Account mAccount;
40 private TextView mTextPreview;
41
42 /**
43 * Creates an empty fragment for previews.
44 * <p/>
45 * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
46 * (for instance, when the device is turned a aside).
47 * <p/>
48 * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
49 * construction
50 */
51 public PreviewTextFragment() {
52 super();
53 mAccount = null;
54 }
55
56 /**
57 * {@inheritDoc}
58 */
59 @Override
60 public View onCreateView(LayoutInflater inflater, ViewGroup container,
61 Bundle savedInstanceState) {
62 super.onCreateView(inflater, container, savedInstanceState);
63 Log_OC.e(TAG, "onCreateView");
64
65
66 View ret = inflater.inflate(R.layout.text_file_preview, container, false);
67
68 mTextPreview = (TextView) ret.findViewById(R.id.text_preview);
69
70 return ret;
71 }
72
73 /**
74 * {@inheritDoc}
75 */
76 @Override
77 public void onCreate(Bundle savedInstanceState) {
78 super.onCreate(savedInstanceState);
79
80 OCFile file = getFile();
81
82 Bundle args = getArguments();
83
84 if (file == null)
85 file = args.getParcelable(FileDisplayActivity.EXTRA_FILE);
86
87 if (mAccount == null)
88 mAccount = args.getParcelable(FileDisplayActivity.EXTRA_ACCOUNT);
89
90
91 if (savedInstanceState == null) {
92 if (file == null) {
93 throw new IllegalStateException("Instanced with a NULL OCFile");
94 }
95 if (mAccount == null) {
96 throw new IllegalStateException("Instanced with a NULL ownCloud Account");
97 }
98 } else {
99 file = savedInstanceState.getParcelable(EXTRA_FILE);
100 mAccount = savedInstanceState.getParcelable(EXTRA_ACCOUNT);
101 }
102 setFile(file);
103 setHasOptionsMenu(true);
104 }
105
106 /**
107 * {@inheritDoc}
108 */
109 @Override
110 public void onSaveInstanceState(Bundle outState) {
111 super.onSaveInstanceState(outState);
112 outState.putParcelable(PreviewImageFragment.EXTRA_FILE, getFile());
113 outState.putParcelable(PreviewImageFragment.EXTRA_ACCOUNT, mAccount);
114 }
115
116 @Override
117 public void onStart() {
118 super.onStart();
119 Log_OC.e(TAG, "onStart");
120 }
121
122 private void loadAndShowTextPreview() {
123 new TextLoadAsyncTask().execute(getFile().getStoragePath(), mTextPreview);
124 }
125
126 /**
127 * Reads the file to preview and shows its contents. Too critical to be anonymous.
128 */
129 private class TextLoadAsyncTask extends AsyncTask<Object, Void, StringWriter> {
130 private final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
131 private TextView mTextView;
132
133 @Override
134 protected void onPreExecute() {
135 showLoadingDialog();
136 }
137
138 @Override
139 protected StringWriter doInBackground(java.lang.Object... params) {
140 if (params.length != 2)
141 throw new IllegalArgumentException("The parameters to " + TextLoadAsyncTask.class.getName() + " must be (1) the file location and (2) the text view to update");
142 final String location = (String) params[0];
143 mTextView = (TextView) params[1];
144
145 FileInputStream inputStream = null;
146 Scanner sc = null;
147 StringWriter source = new StringWriter();
148 BufferedWriter bufferedWriter = new BufferedWriter(source);
149 try {
150 inputStream = new FileInputStream(location);
151 sc = new Scanner(inputStream);
152 while (sc.hasNextLine()) {
153 bufferedWriter.append(sc.nextLine());
154 if (sc.hasNextLine()) bufferedWriter.append("\n");
155 }
156 bufferedWriter.close();
157 IOException exc = sc.ioException();
158 if (exc != null) throw exc;
159 } catch (IOException e) {
160 finish();
161 } finally {
162 if (inputStream != null) {
163 try {
164 inputStream.close();
165 } catch (IOException e) {
166 finish();
167 }
168 }
169 if (sc != null) {
170 sc.close();
171 }
172 }
173 return source;
174 }
175
176 @Override
177 protected void onPostExecute(final StringWriter stringWriter) {
178 mTextView.setText(new String(stringWriter.getBuffer()));
179 mTextView.setVisibility(View.VISIBLE);
180 dismissLoadingDialog();
181 }
182
183 /**
184 * Show loading dialog
185 */
186 public void showLoadingDialog() {
187 // Construct dialog
188 LoadingDialog loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment));
189 FragmentManager fm = getActivity().getSupportFragmentManager();
190 FragmentTransaction ft = fm.beginTransaction();
191 loading.show(ft, DIALOG_WAIT_TAG);
192 }
193
194 /**
195 * Dismiss loading dialog
196 */
197 public void dismissLoadingDialog() {
198 Fragment frag = getActivity().getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
199 if (frag != null) {
200 LoadingDialog loading = (LoadingDialog) frag;
201 loading.dismiss();
202 }
203 }
204 }
205
206 /**
207 * {@inheritDoc}
208 */
209 @Override
210 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
211 super.onCreateOptionsMenu(menu, inflater);
212 inflater.inflate(R.menu.file_actions_menu, menu);
213 }
214
215 /**
216 * {@inheritDoc}
217 */
218 @Override
219 public void onPrepareOptionsMenu(Menu menu) {
220 super.onPrepareOptionsMenu(menu);
221
222 if (mContainerActivity.getStorageManager() != null) {
223 FileMenuFilter mf = new FileMenuFilter(
224 getFile(),
225 mContainerActivity.getStorageManager().getAccount(),
226 mContainerActivity,
227 getSherlockActivity()
228 );
229 mf.filter(menu);
230 }
231
232 // additional restriction for this fragment
233 MenuItem item = menu.findItem(R.id.action_rename_file);
234 if (item != null) {
235 item.setVisible(false);
236 item.setEnabled(false);
237 }
238
239 // additional restriction for this fragment
240 item = menu.findItem(R.id.action_move);
241 if (item != null) {
242 item.setVisible(false);
243 item.setEnabled(false);
244 }
245
246 // this one doesn't make sense since the file has to be down in order to be previewed
247 item = menu.findItem(R.id.action_download_file);
248 if (item != null) {
249 item.setVisible(false);
250 item.setEnabled(false);
251 }
252
253 item = menu.findItem(R.id.action_settings);
254 if (item != null) {
255 item.setVisible(false);
256 item.setEnabled(false);
257 }
258
259 item = menu.findItem(R.id.action_logger);
260 if (item != null) {
261 item.setVisible(false);
262 item.setEnabled(false);
263 }
264
265 item = menu.findItem(R.id.action_sync_file);
266 if (item != null) {
267 item.setVisible(false);
268 item.setEnabled(false);
269 }
270
271 item = menu.findItem(R.id.action_sync_account);
272 if (item != null) {
273 item.setVisible(false);
274 item.setEnabled(false);
275 }
276 }
277
278 /**
279 * {@inheritDoc}
280 */
281 @Override
282 public boolean onOptionsItemSelected(MenuItem item) {
283 switch (item.getItemId()) {
284 case R.id.action_share_file: {
285 mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
286 return true;
287 }
288 case R.id.action_unshare_file: {
289 mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
290 return true;
291 }
292 case R.id.action_open_file_with: {
293 openFile();
294 return true;
295 }
296 case R.id.action_remove_file: {
297 RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(getFile());
298 dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
299 return true;
300 }
301 case R.id.action_see_details: {
302 seeDetails();
303 return true;
304 }
305 case R.id.action_send_file: {
306 sendFile();
307 return true;
308 }
309 case R.id.action_sync_file: {
310 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
311 return true;
312 }
313
314 default:
315 return false;
316 }
317 }
318
319 /**
320 * Update the file of the fragment with file value
321 *
322 * @param file The new file to set
323 */
324 public void updateFile(OCFile file) {
325 setFile(file);
326 }
327
328 private void sendFile() {
329 mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
330 }
331
332 private void seeDetails() {
333 mContainerActivity.showDetails(getFile());
334 }
335
336 @Override
337 public void onPause() {
338 Log_OC.e(TAG, "onPause");
339 super.onPause();
340 }
341
342 @Override
343 public void onResume() {
344 super.onResume();
345 Log_OC.e(TAG, "onResume");
346
347 loadAndShowTextPreview();
348 }
349
350 @Override
351 public void onDestroy() {
352 Log_OC.e(TAG, "onDestroy");
353 super.onDestroy();
354 }
355
356 @Override
357 public void onStop() {
358 super.onStop();
359 Log_OC.e(TAG, "onStop");
360 }
361
362 /**
363 * Opens the previewed file with an external application.
364 */
365 private void openFile() {
366 mContainerActivity.getFileOperationsHelper().openFile(getFile());
367 finish();
368 }
369
370 /**
371 * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewTextFragment} to be previewed.
372 *
373 * @param file File to test if can be previewed.
374 * @return 'True' if the file can be handled by the fragment.
375 */
376 public static boolean canBePreviewed(OCFile file) {
377 return (file != null && file.isDown() && file.isText());
378 }
379
380 /**
381 * Finishes the preview
382 */
383 private void finish() {
384 getActivity().runOnUiThread(new Runnable() {
385 @Override
386 public void run() {
387 getSherlockActivity().onBackPressed();
388 }
389 });
390 }
391 }