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