1 package com
.owncloud
.android
.ui
.preview
;
3 import android
.accounts
.Account
;
4 import android
.content
.Context
;
5 import android
.os
.AsyncTask
;
6 import android
.os
.Bundle
;
7 import android
.view
.LayoutInflater
;
8 import android
.view
.View
;
9 import android
.view
.ViewGroup
;
10 import android
.widget
.BaseAdapter
;
11 import android
.widget
.ListView
;
12 import android
.widget
.ProgressBar
;
13 import android
.widget
.TextView
;
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
.RemoveFileDialogFragment
;
25 import com
.owncloud
.android
.ui
.fragment
.FileFragment
;
27 import java
.io
.BufferedWriter
;
28 import java
.io
.FileInputStream
;
29 import java
.io
.IOException
;
30 import java
.io
.StringWriter
;
31 import java
.util
.ArrayList
;
32 import java
.util
.List
;
33 import java
.util
.Scanner
;
35 public class PreviewTextFragment
extends FileFragment
{
36 private static final String EXTRA_FILE
= "FILE";
37 private static final String EXTRA_ACCOUNT
= "ACCOUNT";
38 private static final String TAG
= PreviewTextFragment
.class.getSimpleName();
40 private Account mAccount
;
41 private ListView mTextPreviewList
;
42 private ProgressBar mProgressBar
;
45 * Creates an empty fragment for previews.
47 * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
48 * (for instance, when the device is turned a aside).
50 * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
53 public PreviewTextFragment() {
62 public View
onCreateView(LayoutInflater inflater
, ViewGroup container
,
63 Bundle savedInstanceState
) {
64 super.onCreateView(inflater
, container
, savedInstanceState
);
65 Log_OC
.e(TAG
, "onCreateView");
68 View ret
= inflater
.inflate(R
.layout
.text_file_preview
, container
, false
);
70 mTextPreviewList
= (ListView
) ret
.findViewById(R
.id
.text_preview_list
);
71 mTextPreviewList
.setAdapter(new TextLineAdapter());
72 mProgressBar
= (ProgressBar
) ret
.findViewById(R
.id
.progress_bar
);
81 public void onCreate(Bundle savedInstanceState
) {
82 super.onCreate(savedInstanceState
);
84 OCFile file
= getFile();
86 Bundle args
= getArguments();
89 file
= args
.getParcelable(FileDisplayActivity
.EXTRA_FILE
);
92 mAccount
= args
.getParcelable(FileDisplayActivity
.EXTRA_ACCOUNT
);
95 if (savedInstanceState
== null
) {
97 throw new IllegalStateException("Instanced with a NULL OCFile");
99 if (mAccount
== null
) {
100 throw new IllegalStateException("Instanced with a NULL ownCloud Account");
103 file
= savedInstanceState
.getParcelable(EXTRA_FILE
);
104 mAccount
= savedInstanceState
.getParcelable(EXTRA_ACCOUNT
);
107 setHasOptionsMenu(true
);
114 public void onSaveInstanceState(Bundle outState
) {
115 super.onSaveInstanceState(outState
);
116 outState
.putParcelable(PreviewImageFragment
.EXTRA_FILE
, getFile());
117 outState
.putParcelable(PreviewImageFragment
.EXTRA_ACCOUNT
, mAccount
);
121 public void onStart() {
123 Log_OC
.e(TAG
, "onStart");
126 private void loadAndShowTextPreview() {
127 new TextLoadAsyncTask().execute(getFile().getStoragePath());
131 * Reads the file to preview and shows its contents. Too critical to be anonymous.
133 private class TextLoadAsyncTask
extends AsyncTask
<Object
, StringWriter
, Void
> {
136 protected void onPreExecute() {
137 ((TextLineAdapter
) mTextPreviewList
.getAdapter()).clear();
141 protected Void
doInBackground(java
.lang
.Object
... params
) {
142 if (params
.length
!= 1)
143 throw new IllegalArgumentException("The parameter to " + TextLoadAsyncTask
.class.getName() + " must be the file location only");
144 final String location
= (String
) params
[0];
146 FileInputStream inputStream
= null
;
149 inputStream
= new FileInputStream(location
);
150 sc
= new Scanner(inputStream
);
151 while (sc
.hasNextLine()) {
152 StringWriter target
= new StringWriter();
153 BufferedWriter bufferedWriter
= new BufferedWriter(target
);
154 if (sc
.hasNextLine())
155 bufferedWriter
.write(sc
.nextLine());
156 bufferedWriter
.close();
157 publishProgress(target
);
159 IOException exc
= sc
.ioException();
160 if (exc
!= null
) throw exc
;
161 } catch (IOException e
) {
164 if (inputStream
!= null
) {
167 } catch (IOException e
) {
179 protected void onProgressUpdate(StringWriter
... values
) {
180 super.onProgressUpdate(values
);
181 //Using a ListView allows to show large text without the UI freeze that happens
182 //when calling TextView#setText() with a large CharSequence
183 ((TextLineAdapter
) mTextPreviewList
.getAdapter()).add(values
[0].toString());
187 protected void onPostExecute(Void aVoid
) {
188 super.onPostExecute(aVoid
);
189 mProgressBar
.setVisibility(View
.GONE
);
190 mTextPreviewList
.setVisibility(View
.VISIBLE
);
194 private class TextLineAdapter
extends BaseAdapter
{
195 private static final int LIST_ITEM_LAYOUT
= R
.layout
.text_file_preview_list_item
;
196 private final List
<String
> items
= new ArrayList
<>();
198 private void add(String line
) {
200 notifyDataSetChanged();
203 private void clear() {
205 notifyDataSetChanged();
209 public int getCount() {
214 public String
getItem(int position
) {
215 if (position
>= items
.size())
216 throw new IllegalArgumentException();
217 return items
.get(position
);
221 public long getItemId(int position
) {
226 public View
getView(int position
, View convertView
, ViewGroup parent
) {
227 ViewHolder viewHolder
;
228 if (convertView
== null
) {
230 ((LayoutInflater
) getActivity().getApplicationContext()
231 .getSystemService(Context
.LAYOUT_INFLATER_SERVICE
))
233 LIST_ITEM_LAYOUT
, null
);
234 viewHolder
= new ViewHolder();
235 viewHolder
.setLineView((TextView
) convertView
.findViewById(R
.id
.text_preview
));
236 convertView
.setTag(viewHolder
);
238 viewHolder
= (ViewHolder
) convertView
.getTag();
241 viewHolder
.getLineView().setText(items
.get(position
));
247 private static class ViewHolder
{
248 private TextView lineView
;
250 private ViewHolder() {
253 public TextView
getLineView() {
257 public void setLineView(TextView lineView
) {
258 this.lineView
= lineView
;
266 public void onCreateOptionsMenu(Menu menu
, MenuInflater inflater
) {
267 super.onCreateOptionsMenu(menu
, inflater
);
268 inflater
.inflate(R
.menu
.file_actions_menu
, menu
);
275 public void onPrepareOptionsMenu(Menu menu
) {
276 super.onPrepareOptionsMenu(menu
);
278 if (mContainerActivity
.getStorageManager() != null
) {
279 FileMenuFilter mf
= new FileMenuFilter(
281 mContainerActivity
.getStorageManager().getAccount(),
283 getSherlockActivity()
288 // additional restriction for this fragment
289 MenuItem item
= menu
.findItem(R
.id
.action_rename_file
);
291 item
.setVisible(false
);
292 item
.setEnabled(false
);
295 // additional restriction for this fragment
296 item
= menu
.findItem(R
.id
.action_move
);
298 item
.setVisible(false
);
299 item
.setEnabled(false
);
302 // this one doesn't make sense since the file has to be down in order to be previewed
303 item
= menu
.findItem(R
.id
.action_download_file
);
305 item
.setVisible(false
);
306 item
.setEnabled(false
);
314 public boolean onOptionsItemSelected(MenuItem item
) {
315 switch (item
.getItemId()) {
316 case R
.id
.action_share_file
: {
317 mContainerActivity
.getFileOperationsHelper().shareFileWithLink(getFile());
320 case R
.id
.action_unshare_file
: {
321 mContainerActivity
.getFileOperationsHelper().unshareFileWithLink(getFile());
324 case R
.id
.action_open_file_with
: {
328 case R
.id
.action_remove_file
: {
329 RemoveFileDialogFragment dialog
= RemoveFileDialogFragment
.newInstance(getFile());
330 dialog
.show(getFragmentManager(), ConfirmationDialogFragment
.FTAG_CONFIRMATION
);
333 case R
.id
.action_see_details
: {
337 case R
.id
.action_send_file
: {
341 case R
.id
.action_sync_file
: {
342 mContainerActivity
.getFileOperationsHelper().syncFile(getFile());
352 * Update the file of the fragment with file value
356 public void updateFile(OCFile file
) {
360 private void sendFile() {
361 mContainerActivity
.getFileOperationsHelper().sendDownloadedFile(getFile());
364 private void seeDetails() {
365 mContainerActivity
.showDetails(getFile());
369 public void onPause() {
370 Log_OC
.e(TAG
, "onPause");
375 public void onResume() {
377 Log_OC
.e(TAG
, "onResume");
379 loadAndShowTextPreview();
383 public void onDestroy() {
384 Log_OC
.e(TAG
, "onDestroy");
389 public void onStop() {
391 Log_OC
.e(TAG
, "onStop");
395 * Opens the previewed file with an external application.
397 private void openFile() {
398 mContainerActivity
.getFileOperationsHelper().openFile(getFile());
403 * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewTextFragment} to be previewed.
405 * @param file File to test if can be previewed.
406 * @return 'True' if the file can be handled by the fragment.
408 public static boolean canBePreviewed(OCFile file
) {
409 return (file
!= null
&& file
.isDown() && file
.isText());
413 * Finishes the preview
415 private void finish() {
416 getSherlockActivity().onBackPressed();