mirror of
https://github.com/nextcloud/android.git
synced 2024-11-27 09:39:25 +03:00
Added text file preview
This commit is contained in:
parent
b22dc8bce6
commit
7cc88a22d1
6 changed files with 809 additions and 395 deletions
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
ownCloud Android client application
|
||||
|
||||
Copyright (C) 2012-2013 ownCloud Inc.
|
||||
|
@ -25,40 +24,37 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/background_color"
|
||||
android:gravity="center"
|
||||
tools:context=".ui.fragment.FilePreviewFragment" >
|
||||
tools:context=".ui.fragment.FilePreviewFragment">
|
||||
|
||||
<FrameLayout
|
||||
<FrameLayout
|
||||
android:id="@+id/visual_area"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_above="@+id/media_controller"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/preview_image_description"
|
||||
android:src="@drawable/logo" />
|
||||
|
||||
<VideoView
|
||||
android:id="@+id/video_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<com.owncloud.android.media.MediaControlView
|
||||
android:id="@id/media_controller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
/>
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_above="@+id/media_controller">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/preview_image_description"
|
||||
android:src="@drawable/logo" />
|
||||
|
||||
<VideoView
|
||||
android:id="@+id/video_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<com.owncloud.android.media.MediaControlView
|
||||
android:id="@id/media_controller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
</RelativeLayout>
|
29
res/layout/text_file_preview.xml
Normal file
29
res/layout/text_file_preview.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/text_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical"
|
||||
android:fillViewport="true"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
</ScrollView>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
|
@ -448,7 +448,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
|
|||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return ((Object) this).hashCode();
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -537,6 +537,14 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
|
|||
getMimeTypeFromName().startsWith("image/"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 'True' if the file is simple text (e.g. not application-dependent, like .doc or .docx)
|
||||
*/
|
||||
public boolean isText() {
|
||||
return !isFolder() && !isAudio() && !isVideo() && !isImage() && ((mMimeType != null && mMimeType.startsWith("text/")) ||
|
||||
getMimeTypeFromName().startsWith("text/"));
|
||||
}
|
||||
|
||||
public String getMimeTypeFromName() {
|
||||
String extension = "";
|
||||
int pos = mRemotePath.lastIndexOf('.');
|
||||
|
@ -562,5 +570,4 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
|
|||
public void setRemoteId(String remoteId) {
|
||||
this.mRemoteId = remoteId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,6 +44,7 @@ import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
|
|||
import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
|
||||
import com.owncloud.android.ui.preview.PreviewImageFragment;
|
||||
import com.owncloud.android.ui.preview.PreviewMediaFragment;
|
||||
import com.owncloud.android.ui.preview.PreviewTextFragment;
|
||||
|
||||
/**
|
||||
* A Fragment that lists all files and folders in a given path.
|
||||
|
@ -125,7 +126,7 @@ public class OCFileListFragment extends ExtendedListFragment {
|
|||
mContainerActivity
|
||||
);
|
||||
setListAdapter(mAdapter);
|
||||
|
||||
|
||||
registerForContextMenu(getListView());
|
||||
getListView().setOnCreateContextMenuListener(this);
|
||||
}
|
||||
|
@ -201,7 +202,8 @@ public class OCFileListFragment extends ExtendedListFragment {
|
|||
if (PreviewImageFragment.canBePreviewed(file)) {
|
||||
// preview image - it handles the download, if needed
|
||||
((FileDisplayActivity)mContainerActivity).startImagePreview(file);
|
||||
|
||||
} else if (PreviewTextFragment.canBePreviewed(file)){
|
||||
((FileDisplayActivity)mContainerActivity).startTextPreview(file);
|
||||
} else if (file.isDown()) {
|
||||
if (PreviewMediaFragment.canBePreviewed(file)) {
|
||||
// media preview
|
||||
|
|
341
src/com/owncloud/android/ui/preview/PreviewTextFragment.java
Normal file
341
src/com/owncloud/android/ui/preview/PreviewTextFragment.java
Normal file
|
@ -0,0 +1,341 @@
|
|||
package com.owncloud.android.ui.preview;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.actionbarsherlock.view.Menu;
|
||||
import com.actionbarsherlock.view.MenuInflater;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.files.FileMenuFilter;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
|
||||
import com.owncloud.android.ui.fragment.FileFragment;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class PreviewTextFragment extends FileFragment {
|
||||
private static final String EXTRA_FILE = "FILE";
|
||||
private static final String EXTRA_ACCOUNT = "ACCOUNT";
|
||||
private static final String TAG = PreviewTextFragment.class.getSimpleName();
|
||||
|
||||
private Account mAccount;
|
||||
private TextView mTextPreview;
|
||||
private ProgressBar mProgressBar;
|
||||
private ScrollView mScrollView;
|
||||
|
||||
/**
|
||||
* Creates an empty fragment for previews.
|
||||
* <p/>
|
||||
* MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
|
||||
* (for instance, when the device is turned a aside).
|
||||
* <p/>
|
||||
* DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
|
||||
* construction
|
||||
*/
|
||||
public PreviewTextFragment() {
|
||||
super();
|
||||
mAccount = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
Log_OC.e(TAG, "onCreateView");
|
||||
|
||||
|
||||
View ret = inflater.inflate(R.layout.text_file_preview, container, false);
|
||||
|
||||
mScrollView = (ScrollView) ret.findViewById(R.id.text_scrollview);
|
||||
mTextPreview = (TextView) ret.findViewById(R.id.text_preview);
|
||||
mProgressBar = (ProgressBar) ret.findViewById(R.id.progress_bar);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
OCFile file = getFile();
|
||||
|
||||
Bundle args = getArguments();
|
||||
|
||||
if (file == null)
|
||||
file = args.getParcelable(FileDisplayActivity.EXTRA_FILE);
|
||||
|
||||
if (mAccount == null)
|
||||
mAccount = args.getParcelable(FileDisplayActivity.EXTRA_ACCOUNT);
|
||||
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
if (file == null) {
|
||||
throw new IllegalStateException("Instanced with a NULL OCFile");
|
||||
}
|
||||
if (mAccount == null) {
|
||||
throw new IllegalStateException("Instanced with a NULL ownCloud Account");
|
||||
}
|
||||
} else {
|
||||
file = savedInstanceState.getParcelable(EXTRA_FILE);
|
||||
mAccount = savedInstanceState.getParcelable(EXTRA_ACCOUNT);
|
||||
}
|
||||
setFile(file);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putParcelable(PreviewImageFragment.EXTRA_FILE, getFile());
|
||||
outState.putParcelable(PreviewImageFragment.EXTRA_ACCOUNT, mAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
Log_OC.e(TAG, "onStart");
|
||||
|
||||
loadAndShowTextPreview(getFile().getStoragePath(), mTextPreview);
|
||||
}
|
||||
|
||||
private void loadAndShowTextPreview(String location, TextView textView) {
|
||||
new TextLoadAsyncTask().execute(location, textView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the file to preview and shows its contents. Too critical to be anonymous.
|
||||
*/
|
||||
private class TextLoadAsyncTask extends AsyncTask<Object, Void, StringWriter> {
|
||||
TextView mTextView;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringWriter doInBackground(java.lang.Object... params) {
|
||||
if (params.length != 2)
|
||||
throw new IllegalArgumentException("The parameters to " + TextLoadAsyncTask.class.getName() + " must be (1) the file location and (2) the text view to update");
|
||||
final String location = (String) params[0];
|
||||
mTextView = (TextView) params[1];
|
||||
|
||||
FileInputStream inputStream = null;
|
||||
Scanner sc = null;
|
||||
StringWriter source = new StringWriter();
|
||||
BufferedWriter bufferedWriter = new BufferedWriter(source);
|
||||
try {
|
||||
inputStream = new FileInputStream(location);
|
||||
sc = new Scanner(inputStream);
|
||||
while (sc.hasNextLine()) {
|
||||
bufferedWriter.append(sc.nextLine());
|
||||
if (sc.hasNextLine()) bufferedWriter.append("\n");
|
||||
}
|
||||
bufferedWriter.close();
|
||||
IOException exc = sc.ioException();
|
||||
if (exc != null) throw exc;
|
||||
} catch (IOException e) {
|
||||
finish();
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
if (sc != null) {
|
||||
sc.close();
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final StringWriter stringWriter) {
|
||||
super.onPostExecute(stringWriter);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
mScrollView.setVisibility(View.VISIBLE);
|
||||
mTextView.setText(new String(stringWriter.getBuffer()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.file_actions_menu, menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
|
||||
if (mContainerActivity.getStorageManager() != null) {
|
||||
FileMenuFilter mf = new FileMenuFilter(
|
||||
getFile(),
|
||||
mContainerActivity.getStorageManager().getAccount(),
|
||||
mContainerActivity,
|
||||
getSherlockActivity()
|
||||
);
|
||||
mf.filter(menu);
|
||||
}
|
||||
|
||||
// additional restriction for this fragment
|
||||
MenuItem item = menu.findItem(R.id.action_rename_file);
|
||||
if (item != null) {
|
||||
item.setVisible(false);
|
||||
item.setEnabled(false);
|
||||
}
|
||||
|
||||
// additional restriction for this fragment
|
||||
item = menu.findItem(R.id.action_move);
|
||||
if (item != null) {
|
||||
item.setVisible(false);
|
||||
item.setEnabled(false);
|
||||
}
|
||||
|
||||
// this one doesn't make sense since the file has to be down in order to be previewed
|
||||
item = menu.findItem(R.id.action_download_file);
|
||||
if (item != null) {
|
||||
item.setVisible(false);
|
||||
item.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_share_file: {
|
||||
mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
|
||||
return true;
|
||||
}
|
||||
case R.id.action_unshare_file: {
|
||||
mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
|
||||
return true;
|
||||
}
|
||||
case R.id.action_open_file_with: {
|
||||
openFile();
|
||||
return true;
|
||||
}
|
||||
case R.id.action_remove_file: {
|
||||
RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(getFile());
|
||||
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_see_details: {
|
||||
seeDetails();
|
||||
return true;
|
||||
}
|
||||
case R.id.action_send_file: {
|
||||
sendFile();
|
||||
return true;
|
||||
}
|
||||
case R.id.action_sync_file: {
|
||||
mContainerActivity.getFileOperationsHelper().syncFile(getFile());
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the file of the fragment with file value
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
public void updateFile(OCFile file) {
|
||||
setFile(file);
|
||||
}
|
||||
|
||||
private void sendFile() {
|
||||
mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
|
||||
}
|
||||
|
||||
private void seeDetails() {
|
||||
mContainerActivity.showDetails(getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
Log_OC.e(TAG, "onPause");
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log_OC.e(TAG, "onResume");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log_OC.e(TAG, "onDestroy");
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
Log_OC.e(TAG, "onStop");
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the previewed file with an external application.
|
||||
*/
|
||||
private void openFile() {
|
||||
mContainerActivity.getFileOperationsHelper().openFile(getFile());
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to test if an {@link OCFile} can be passed to a {@link PreviewTextFragment} to be previewed.
|
||||
*
|
||||
* @param file File to test if can be previewed.
|
||||
* @return 'True' if the file can be handled by the fragment.
|
||||
*/
|
||||
public static boolean canBePreviewed(OCFile file) {
|
||||
return (file != null && file.isDown() && file.isText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the preview
|
||||
*/
|
||||
private void finish() {
|
||||
getSherlockActivity().onBackPressed();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue