X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/48f13c8adc5c4b9bc4ca96bf13939a7d7cfae562..a99f74bd9e09ed9acc74b0fe276ed030b91fc85d:/src/com/owncloud/android/ui/fragment/FileDetailFragment.java diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java index d251883a..2d46a55c 100644 --- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -1,9 +1,10 @@ /* ownCloud Android client application * Copyright (C) 2011 Bartek Przybylski + * Copyright (C) 2012-2013 ownCloud Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or + * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -18,11 +19,9 @@ package com.owncloud.android.ui.fragment; import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; @@ -32,10 +31,7 @@ import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; -import org.apache.jackrabbit.webdav.client.methods.DavMethodBase; -import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; -import org.json.JSONException; import org.json.JSONObject; import android.accounts.Account; @@ -47,7 +43,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources.NotFoundException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; @@ -56,6 +51,7 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; +import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentTransaction; import android.util.Log; import android.view.Display; @@ -63,7 +59,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.view.WindowManager.LayoutParams; import android.webkit.MimeTypeMap; import android.widget.Button; import android.widget.CheckBox; @@ -71,7 +66,6 @@ import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; -import com.actionbarsherlock.app.SherlockDialogFragment; import com.actionbarsherlock.app.SherlockFragment; import com.owncloud.android.AccountUtils; import com.owncloud.android.DisplayUtils; @@ -81,9 +75,22 @@ import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileDownloader; import com.owncloud.android.files.services.FileObserverService; import com.owncloud.android.files.services.FileUploader; +import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; +import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.network.OwnCloudClientUtils; +import com.owncloud.android.operations.OnRemoteOperationListener; +import com.owncloud.android.operations.RemoteOperation; +import com.owncloud.android.operations.RemoteOperationResult; +import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.operations.RemoveFileOperation; +import com.owncloud.android.operations.RenameFileOperation; +import com.owncloud.android.operations.SynchronizeFileOperation; +import com.owncloud.android.ui.activity.ConflictsResolveActivity; import com.owncloud.android.ui.activity.FileDetailActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; +import com.owncloud.android.ui.activity.TransferServiceGetter; +import com.owncloud.android.ui.dialog.EditNameDialog; +import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener; import com.owncloud.android.utils.OwnCloudVersion; import com.owncloud.android.R; @@ -97,7 +104,7 @@ import eu.alefzero.webdav.WebdavUtils; * */ public class FileDetailFragment extends SherlockFragment implements - OnClickListener, ConfirmationDialogFragment.ConfirmationDialogFragmentListener { + OnClickListener, ConfirmationDialogFragment.ConfirmationDialogFragmentListener, OnRemoteOperationListener, EditNameDialogListener { public static final String EXTRA_FILE = "FILE"; public static final String EXTRA_ACCOUNT = "ACCOUNT"; @@ -108,12 +115,17 @@ public class FileDetailFragment extends SherlockFragment implements private View mView; private OCFile mFile; private Account mAccount; + private FileDataStorageManager mStorageManager; private ImageView mPreview; private DownloadFinishReceiver mDownloadFinishReceiver; private UploadFinishReceiver mUploadFinishReceiver; + + private Handler mHandler; + private RemoteOperation mLastRemoteOperation; + private DialogFragment mCurrentDialog; - private static final String TAG = "FileDetailFragment"; + private static final String TAG = FileDetailFragment.class.getSimpleName(); public static final String FTAG = "FileDetails"; public static final String FTAG_CONFIRMATION = "REMOVE_CONFIRMATION_FRAGMENT"; @@ -126,6 +138,7 @@ public class FileDetailFragment extends SherlockFragment implements public FileDetailFragment() { mFile = null; mAccount = null; + mStorageManager = null; mLayout = R.layout.file_details_empty; } @@ -138,31 +151,21 @@ public class FileDetailFragment extends SherlockFragment implements * @param fileToDetail An {@link OCFile} to show in the fragment * @param ocAccount An ownCloud account; needed to start downloads */ - public FileDetailFragment(OCFile fileToDetail, Account ocAccount){ + public FileDetailFragment(OCFile fileToDetail, Account ocAccount) { mFile = fileToDetail; mAccount = ocAccount; + mStorageManager = null; // we need a context to init this; the container activity is not available yet at this moment mLayout = R.layout.file_details_empty; - - if(fileToDetail != null && ocAccount != null) { - mLayout = R.layout.file_details_fragment; - } } - - /** - * {@inheritDoc} - */ + @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - mContainerActivity = (ContainerActivity) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity"); - } + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mHandler = new Handler(); } - + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -173,6 +176,10 @@ public class FileDetailFragment extends SherlockFragment implements mAccount = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_ACCOUNT); } + if(mFile != null && mAccount != null) { + mLayout = R.layout.file_details_fragment; + } + View view = null; view = inflater.inflate(mLayout, container, false); mView = view; @@ -187,11 +194,37 @@ public class FileDetailFragment extends SherlockFragment implements mPreview = (ImageView)mView.findViewById(R.id.fdPreview); } - updateFileDetails(); + updateFileDetails(false); return view; } + /** + * {@inheritDoc} + */ + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mContainerActivity = (ContainerActivity) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement " + FileDetailFragment.ContainerActivity.class.getSimpleName()); + } + } + + + /** + * {@inheritDoc} + */ + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + if (mAccount != null) { + mStorageManager = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());; + } + } + + @Override public void onSaveInstanceState(Bundle outState) { Log.i(getClass().toString(), "onSaveInstanceState() start"); @@ -244,43 +277,75 @@ public class FileDetailFragment extends SherlockFragment implements public void onClick(View v) { switch (v.getId()) { case R.id.fdDownloadBtn: { - Intent i = new Intent(getActivity(), FileDownloader.class); - i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount); - i.putExtra(FileDownloader.EXTRA_REMOTE_PATH, mFile.getRemotePath()); - i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath()); - i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength()); - - // update ui - setButtonsForTransferring(); + FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder(); + FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder(); + if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile)) { + downloaderBinder.cancel(mAccount, mFile); + if (mFile.isDown()) { + setButtonsForDown(); + } else { + setButtonsForRemote(); + } + + } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile)) { + uploaderBinder.cancel(mAccount, mFile); + if (!mFile.fileExists()) { + // TODO make something better + if (getActivity() instanceof FileDisplayActivity) { + // double pane + FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction(); + transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null), FTAG); // empty FileDetailFragment + transaction.commit(); + mContainerActivity.onFileStateChanged(); + } else { + getActivity().finish(); + } + + } else if (mFile.isDown()) { + setButtonsForDown(); + } else { + setButtonsForRemote(); + } + + } else { + mLastRemoteOperation = new SynchronizeFileOperation(mFile, null, mStorageManager, mAccount, true, false, getActivity()); + WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext()); + mLastRemoteOperation.execute(wc, this, mHandler); - getActivity().startService(i); - mContainerActivity.onFileStateChanged(); // this is not working; it is performed before the fileDownloadService registers it as 'in progress' + // update ui + boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; + getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); + setButtonsForTransferring(); // disable button immediately, although the synchronization does not result in a file transference + + } break; } case R.id.fdKeepInSync: { CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync); mFile.setKeepInSync(cb.isChecked()); - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver()); - fdsm.saveFile(mFile); - if (mFile.keepInSync()) { - onClick(getView().findViewById(R.id.fdDownloadBtn)); - } else { - mContainerActivity.onFileStateChanged(); // put inside 'else' to not call it twice (here, and in the virtual click on fdDownloadBtn) - } + mStorageManager.saveFile(mFile); + + /// register the OCFile instance in the observer service to monitor local updates; + /// if necessary, the file is download Intent intent = new Intent(getActivity().getApplicationContext(), FileObserverService.class); intent.putExtra(FileObserverService.KEY_FILE_CMD, (cb.isChecked()? FileObserverService.CMD_ADD_OBSERVED_FILE: FileObserverService.CMD_DEL_OBSERVED_FILE)); - intent.putExtra(FileObserverService.KEY_CMD_ARG, mFile.getStoragePath()); + intent.putExtra(FileObserverService.KEY_CMD_ARG_FILE, mFile); + intent.putExtra(FileObserverService.KEY_CMD_ARG_ACCOUNT, mAccount); + Log.e(TAG, "starting observer service"); getActivity().startService(intent); + + if (mFile.keepInSync()) { + onClick(getView().findViewById(R.id.fdDownloadBtn)); // force an immediate synchronization + } break; } case R.id.fdRenameBtn: { - EditNameFragment dialog = EditNameFragment.newInstance(mFile.getFileName()); + EditNameDialog dialog = EditNameDialog.newInstance(getString(R.string.rename_dialog_title), mFile.getFileName(), this); dialog.show(getFragmentManager(), "nameeditdialog"); - dialog.setOnDismissListener(this); break; } case R.id.fdRemoveBtn: { @@ -291,7 +356,8 @@ public class FileDetailFragment extends SherlockFragment implements mFile.isDown() ? R.string.confirmation_remove_local : -1, R.string.common_cancel); confDialog.setOnConfirmationListener(this); - confDialog.show(getFragmentManager(), FTAG_CONFIRMATION); + mCurrentDialog = confDialog; + mCurrentDialog.show(getFragmentManager(), FTAG_CONFIRMATION); break; } case R.id.fdOpenBtn: { @@ -310,8 +376,13 @@ public class FileDetailFragment extends SherlockFragment implements try { Intent i = new Intent(Intent.ACTION_VIEW); mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1)); - if (mimeType != null && !mimeType.equals(mFile.getMimetype())) { - i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mimeType); + if (mimeType == null || !mimeType.equals(mFile.getMimetype())) { + if (mimeType != null) { + i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mimeType); + } else { + // desperate try + i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), "*/*"); + } i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); startActivity(i); toastIt = false; @@ -349,30 +420,39 @@ public class FileDetailFragment extends SherlockFragment implements @Override public void onConfirmation(String callerTag) { if (callerTag.equals(FTAG_CONFIRMATION)) { - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver()); - if (fdsm.getFileById(mFile.getFileId()) != null) { - new Thread(new RemoveRunnable(mFile, mAccount, new Handler())).start(); + if (mStorageManager.getFileById(mFile.getFileId()) != null) { + mLastRemoteOperation = new RemoveFileOperation( mFile, + true, + mStorageManager); + WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext()); + mLastRemoteOperation.execute(wc, this, mHandler); + boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); } } + mCurrentDialog.dismiss(); + mCurrentDialog = null; } @Override public void onNeutral(String callerTag) { - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver()); File f = null; if (mFile.isDown() && (f = new File(mFile.getStoragePath())).exists()) { f.delete(); mFile.setStoragePath(null); - fdsm.saveFile(mFile); + mStorageManager.saveFile(mFile); updateFileDetails(mFile, mAccount); } + mCurrentDialog.dismiss(); + mCurrentDialog = null; } @Override public void onCancel(String callerTag) { Log.d(TAG, "REMOVAL CANCELED"); + mCurrentDialog.dismiss(); + mCurrentDialog = null; } @@ -382,7 +462,7 @@ public class FileDetailFragment extends SherlockFragment implements * @return True when the fragment was created with the empty layout. */ public boolean isEmpty() { - return mLayout == R.layout.file_details_empty; + return (mLayout == R.layout.file_details_empty || mFile == null || mAccount == null); } @@ -401,22 +481,34 @@ public class FileDetailFragment extends SherlockFragment implements */ public void updateFileDetails(OCFile file, Account ocAccount) { mFile = file; + if (ocAccount != null && ( + mStorageManager == null || + (mAccount != null && !mAccount.equals(ocAccount)) + )) { + mStorageManager = new FileDataStorageManager(ocAccount, getActivity().getApplicationContext().getContentResolver()); + } mAccount = ocAccount; - updateFileDetails(); + updateFileDetails(false); } /** * Updates the view with all relevant details about that file. + * + * TODO Remove parameter when the transferring state of files is kept in database. + * + * @param transferring Flag signaling if the file should be considered as downloading or uploading, + * although {@link FileDownloaderBinder#isDownloading(Account, OCFile)} and + * {@link FileUploaderBinder#isUploading(Account, OCFile)} return false. + * */ - public void updateFileDetails() { + public void updateFileDetails(boolean transferring) { if (mFile != null && mAccount != null && mLayout == R.layout.file_details_fragment) { // set file details setFilename(mFile.getFileName()); - setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile - .getMimetype())); + setFiletype(mFile.getMimetype()); setFilesize(mFile.getFileLength()); if(ocVersionSupportsTimeCreated()){ setTimeCreated(mFile.getCreationTimestamp()); @@ -428,7 +520,10 @@ public class FileDetailFragment extends SherlockFragment implements cb.setChecked(mFile.keepInSync()); // configure UI for depending upon local state of the file - if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath()) || FileUploader.isUploading(mAccount, mFile.getRemotePath())) { + //if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath()) || FileUploader.isUploading(mAccount, mFile.getRemotePath())) { + FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder(); + FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder(); + if (transferring || (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile)) || (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile))) { setButtonsForTransferring(); } else if (mFile.isDown()) { @@ -441,9 +536,11 @@ public class FileDetailFragment extends SherlockFragment implements setButtonsForDown(); } else { + // TODO load default preview image; when the local file is removed, the preview remains there setButtonsForRemote(); } } + getView().invalidate(); } @@ -463,8 +560,14 @@ public class FileDetailFragment extends SherlockFragment implements */ private void setFiletype(String mimetype) { TextView tv = (TextView) getView().findViewById(R.id.fdType); - if (tv != null) - tv.setText(mimetype); + if (tv != null) { + String printableMimetype = DisplayUtils.convertMIMEtoPrettyPrint(mimetype);; + tv.setText(printableMimetype); + } + ImageView iv = (ImageView) getView().findViewById(R.id.fdIcon); + if (iv != null) { + iv.setImageResource(DisplayUtils.getResourceId(mimetype)); + } } /** @@ -508,13 +611,14 @@ public class FileDetailFragment extends SherlockFragment implements private void setButtonsForTransferring() { if (!isEmpty()) { Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn); - //downloadButton.setText(R.string.filedetails_download_in_progress); // ugly - downloadButton.setEnabled(false); // TODO replace it with a 'cancel download' button + downloadButton.setText(R.string.common_cancel); + //downloadButton.setEnabled(false); // let's protect the user from himself ;) ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false); ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(false); ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(false); + getView().findViewById(R.id.fdKeepInSync).setEnabled(false); } } @@ -524,12 +628,12 @@ public class FileDetailFragment extends SherlockFragment implements private void setButtonsForDown() { if (!isEmpty()) { Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn); - //downloadButton.setText(R.string.filedetails_redownload); // ugly - downloadButton.setEnabled(true); + downloadButton.setText(R.string.filedetails_sync_file); ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(true); ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true); ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true); + getView().findViewById(R.id.fdKeepInSync).setEnabled(true); } } @@ -539,12 +643,12 @@ public class FileDetailFragment extends SherlockFragment implements private void setButtonsForRemote() { if (!isEmpty()) { Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn); - //downloadButton.setText(R.string.filedetails_download); // unnecessary - downloadButton.setEnabled(true); + downloadButton.setText(R.string.filedetails_download); ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false); ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true); ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true); + getView().findViewById(R.id.fdKeepInSync).setEnabled(true); } } @@ -574,7 +678,7 @@ public class FileDetailFragment extends SherlockFragment implements * * @author David A. Velasco */ - public interface ContainerActivity { + public interface ContainerActivity extends TransferServiceGetter { /** * Callback method invoked when the detail fragment wants to notice its container @@ -607,9 +711,9 @@ public class FileDetailFragment extends SherlockFragment implements String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH); if (mFile.getRemotePath().equals(downloadedRemotePath)) { if (downloadWasFine) { - mFile.setStoragePath(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH)); // updates the local object without accessing the database again + mFile = mStorageManager.getFileByPath(downloadedRemotePath); } - updateFileDetails(); // it updates the buttons; must be called although !downloadWasFine + updateFileDetails(false); // it updates the buttons; must be called although !downloadWasFine } } } @@ -634,12 +738,19 @@ public class FileDetailFragment extends SherlockFragment implements if (!isEmpty() && accountName.equals(mAccount.name)) { boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false); String uploadRemotePath = intent.getStringExtra(FileUploader.EXTRA_REMOTE_PATH); - if (mFile.getRemotePath().equals(uploadRemotePath)) { + boolean renamedInUpload = mFile.getRemotePath().equals(intent.getStringExtra(FileUploader.EXTRA_OLD_REMOTE_PATH)); + if (mFile.getRemotePath().equals(uploadRemotePath) || + renamedInUpload) { if (uploadWasFine) { - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver()); - mFile = fdsm.getFileByPath(mFile.getRemotePath()); + mFile = mStorageManager.getFileByPath(uploadRemotePath); + } + if (renamedInUpload) { + String newName = (new File(uploadRemotePath)).getName(); + Toast msg = Toast.makeText(getActivity().getApplicationContext(), String.format(getString(R.string.filedetails_renamed_in_upload_msg), newName), Toast.LENGTH_LONG); + msg.show(); } - updateFileDetails(); // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server + getSherlockActivity().removeStickyBroadcast(intent); // not the best place to do this; a small refactorization of BroadcastReceivers should be done + updateFileDetails(false); // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server } } } @@ -647,6 +758,7 @@ public class FileDetailFragment extends SherlockFragment implements // this is a temporary class for sharing purposes, it need to be replaced in transfer service + @SuppressWarnings("unused") private class ShareRunnable implements Runnable { private String mPath; @@ -739,17 +851,7 @@ public class FileDetailFragment extends SherlockFragment implements String uri = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + SHARED_PATH + token; Log.d("Actions:shareFile ok", "url: " + uri); - } catch (HttpException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); } @@ -759,309 +861,21 @@ public class FileDetailFragment extends SherlockFragment implements } } - public void onDismiss(EditNameFragment dialog) { - if (dialog instanceof EditNameFragment) { - if (((EditNameFragment)dialog).getResult()) { - String newFilename = ((EditNameFragment)dialog).getNewFilename(); - Log.d(TAG, "name edit dialog dismissed with new name " + newFilename); - if (!newFilename.equals(mFile.getFileName())) { - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver()); - if (fdsm.getFileById(mFile.getFileId()) != null) { - OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath() + newFilename); - newFile.setCreationTimestamp(mFile.getCreationTimestamp()); - newFile.setFileId(mFile.getFileId()); - newFile.setFileLength(mFile.getFileLength()); - newFile.setKeepInSync(mFile.keepInSync()); - newFile.setLastSyncDate(mFile.getLastSyncDate()); - newFile.setMimetype(mFile.getMimetype()); - newFile.setModificationTimestamp(mFile.getModificationTimestamp()); - newFile.setParentId(mFile.getParentId()); - boolean localRenameFails = false; - if (mFile.isDown()) { - File f = new File(mFile.getStoragePath()); - Log.e(TAG, f.getAbsolutePath()); - localRenameFails = !(f.renameTo(new File(f.getParent() + File.separator + newFilename))); - Log.e(TAG, f.getParent() + File.separator + newFilename); - newFile.setStoragePath(f.getParent() + File.separator + newFilename); - } - - if (localRenameFails) { - Toast msg = Toast.makeText(getActivity(), R.string.rename_local_fail_msg, Toast.LENGTH_LONG); - msg.show(); - - } else { - new Thread(new RenameRunnable(mFile, newFile, mAccount, new Handler())).start(); - boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; - getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); - } - - } - } - } - } else { - Log.e(TAG, "Unknown dialog instance passed to onDismissDalog: " + dialog.getClass().getCanonicalName()); - } - - } - - private class RenameRunnable implements Runnable { - - Account mAccount; - OCFile mOld, mNew; - Handler mHandler; - - public RenameRunnable(OCFile oldFile, OCFile newFile, Account account, Handler handler) { - mOld = oldFile; - mNew = newFile; - mAccount = account; - mHandler = handler; - } - - public void run() { + public void onDismiss(EditNameDialog dialog) { + if (dialog.getResult()) { + String newFilename = dialog.getNewFilename(); + Log.d(TAG, "name edit dialog dismissed with new name " + newFilename); + mLastRemoteOperation = new RenameFileOperation( mFile, + mAccount, + newFilename, + new FileDataStorageManager(mAccount, getActivity().getContentResolver())); WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext()); - AccountManager am = AccountManager.get(getSherlockActivity()); - String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL); - OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION)); - String webdav_path = AccountUtils.getWebdavPath(ocv); - Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath())); - - Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath())); - LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()), - Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath())); - - boolean success = false; - try { - int status = wc.executeMethod(move); - success = move.succeeded(); - move.getResponseBodyAsString(); // exhaust response, although not interesting - Log.d(TAG, "Move returned status: " + status); - - } catch (HttpException e) { - Log.e(TAG, "HTTP Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e); - - } catch (IOException e) { - Log.e(TAG, "I/O Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e); - - } catch (Exception e) { - Log.e(TAG, "Unexpected exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e); - - } finally { - move.releaseConnection(); - } - - if (success) { - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver()); - fdsm.removeFile(mOld, false); - fdsm.saveFile(mNew); - mFile = mNew; - mHandler.post(new Runnable() { - @Override - public void run() { - boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; - getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); - updateFileDetails(mFile, mAccount); - mContainerActivity.onFileStateChanged(); - } - }); - - } else { - mHandler.post(new Runnable() { - @Override - public void run() { - // undo the local rename - if (mNew.isDown()) { - File f = new File(mNew.getStoragePath()); - if (!f.renameTo(new File(mOld.getStoragePath()))) { - // the local rename undoing failed; last chance: save the new local storage path in the old file - mFile.setStoragePath(mNew.getStoragePath()); - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver()); - fdsm.saveFile(mFile); - } - } - boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; - getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); - try { - Toast msg = Toast.makeText(getActivity(), R.string.rename_server_fail_msg, Toast.LENGTH_LONG); - msg.show(); - - } catch (NotFoundException e) { - e.printStackTrace(); - } - } - }); - } - } - private class LocalMoveMethod extends DavMethodBase { - - public LocalMoveMethod(String uri, String dest) { - super(uri); - addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest)); - } - - @Override - public String getName() { - return "MOVE"; - } - - @Override - protected boolean isSuccess(int status) { - return status == 201 || status == 204; - } - + mLastRemoteOperation.execute(wc, this, mHandler); + boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; + getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); } } - private static class EditNameFragment extends SherlockDialogFragment implements OnClickListener { - - private String mNewFilename; - private boolean mResult; - private FileDetailFragment mListener; - - static public EditNameFragment newInstance(String filename) { - EditNameFragment f = new EditNameFragment(); - Bundle args = new Bundle(); - args.putString("filename", filename); - f.setArguments(args); - return f; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.edit_box_dialog, container, false); - - String currentName = getArguments().getString("filename"); - if (currentName == null) - currentName = ""; - - ((Button)v.findViewById(R.id.cancel)).setOnClickListener(this); - ((Button)v.findViewById(R.id.ok)).setOnClickListener(this); - ((TextView)v.findViewById(R.id.user_input)).setText(currentName); - ((TextView)v.findViewById(R.id.user_input)).requestFocus(); - getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); - - mResult = false; - return v; - } - - @Override - public void onClick(View view) { - switch (view.getId()) { - case R.id.ok: { - mNewFilename = ((TextView)getView().findViewById(R.id.user_input)).getText().toString(); - mResult = true; - } - case R.id.cancel: { // fallthought - dismiss(); - mListener.onDismiss(this); - } - } - } - - void setOnDismissListener(FileDetailFragment listener) { - mListener = listener; - } - - public String getNewFilename() { - return mNewFilename; - } - - // true if user click ok - public boolean getResult() { - return mResult; - } - - } - - private class RemoveRunnable implements Runnable { - - Account mAccount; - OCFile mFileToRemove; - Handler mHandler; - - public RemoveRunnable(OCFile fileToRemove, Account account, Handler handler) { - mFileToRemove = fileToRemove; - mAccount = account; - mHandler = handler; - } - - public void run() { - WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext()); - AccountManager am = AccountManager.get(getSherlockActivity()); - String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL); - OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION)); - String webdav_path = AccountUtils.getWebdavPath(ocv); - Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath())); - - DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath())); - - boolean success = false; - int status = -1; - try { - status = wc.executeMethod(delete); - success = (delete.succeeded()); - delete.getResponseBodyAsString(); // exhaust the response, although not interesting - Log.d(TAG, "Delete: returned status " + status); - - } catch (HttpException e) { - Log.e(TAG, "HTTP Exception removing file " + mFileToRemove.getRemotePath(), e); - - } catch (IOException e) { - Log.e(TAG, "I/O Exception removing file " + mFileToRemove.getRemotePath(), e); - - } catch (Exception e) { - Log.e(TAG, "Unexpected exception removing file " + mFileToRemove.getRemotePath(), e); - - } finally { - delete.releaseConnection(); - } - - if (success) { - FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver()); - fdsm.removeFile(mFileToRemove, true); - mHandler.post(new Runnable() { - @Override - public void run() { - boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; - getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); - try { - Toast msg = Toast.makeText(getActivity().getApplicationContext(), R.string.remove_success_msg, Toast.LENGTH_LONG); - msg.show(); - if (inDisplayActivity) { - // double pane - FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction(); - transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment - transaction.commit(); - mContainerActivity.onFileStateChanged(); - - } else { - getActivity().finish(); - } - - } catch (NotFoundException e) { - e.printStackTrace(); - } - } - }); - - } else { - mHandler.post(new Runnable() { - @Override - public void run() { - boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; - getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); - try { - Toast msg = Toast.makeText(getActivity(), R.string.remove_fail_msg, Toast.LENGTH_LONG); - msg.show(); - - } catch (NotFoundException e) { - e.printStackTrace(); - } - } - }); - } - } - - } class BitmapLoader extends AsyncTask { @SuppressLint({ "NewApi", "NewApi", "NewApi" }) // to avoid Lint errors since Android SDK r20 @@ -1136,6 +950,113 @@ public class FileDetailFragment extends SherlockFragment implements } } + + /** + * {@inheritDoc} + */ + @Override + public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { + if (operation.equals(mLastRemoteOperation)) { + if (operation instanceof RemoveFileOperation) { + onRemoveFileOperationFinish((RemoveFileOperation)operation, result); + + } else if (operation instanceof RenameFileOperation) { + onRenameFileOperationFinish((RenameFileOperation)operation, result); + + } else if (operation instanceof SynchronizeFileOperation) { + onSynchronizeFileOperationFinish((SynchronizeFileOperation)operation, result); + } + } + } + + private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) { + boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; + getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); + + if (result.isSuccess()) { + Toast msg = Toast.makeText(getActivity().getApplicationContext(), R.string.remove_success_msg, Toast.LENGTH_LONG); + msg.show(); + if (inDisplayActivity) { + // double pane + FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction(); + transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment + transaction.commit(); + mContainerActivity.onFileStateChanged(); + } else { + getActivity().finish(); + } + + } else { + Toast msg = Toast.makeText(getActivity(), R.string.remove_fail_msg, Toast.LENGTH_LONG); + msg.show(); + if (result.isSslRecoverableException()) { + // TODO show the SSL warning dialog + } + } + } + + private void onRenameFileOperationFinish(RenameFileOperation operation, RemoteOperationResult result) { + boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; + getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); + + if (result.isSuccess()) { + updateFileDetails(((RenameFileOperation)operation).getFile(), mAccount); + mContainerActivity.onFileStateChanged(); + + } else { + if (result.getCode().equals(ResultCode.INVALID_LOCAL_FILE_NAME)) { + Toast msg = Toast.makeText(getActivity(), R.string.rename_local_fail_msg, Toast.LENGTH_LONG); + msg.show(); + // TODO throw again the new rename dialog + } else { + Toast msg = Toast.makeText(getActivity(), R.string.rename_server_fail_msg, Toast.LENGTH_LONG); + msg.show(); + if (result.isSslRecoverableException()) { + // TODO show the SSL warning dialog + } + } + } + } + + private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation, RemoteOperationResult result) { + boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity; + getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT); + + if (!result.isSuccess()) { + if (result.getCode() == ResultCode.SYNC_CONFLICT) { + Intent i = new Intent(getActivity(), ConflictsResolveActivity.class); + i.putExtra(ConflictsResolveActivity.EXTRA_FILE, mFile); + i.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, mAccount); + startActivity(i); + + } else { + Toast msg = Toast.makeText(getActivity(), R.string.sync_file_fail_msg, Toast.LENGTH_LONG); + msg.show(); + } + + if (mFile.isDown()) { + setButtonsForDown(); + + } else { + setButtonsForRemote(); + } + + } else { + if (operation.transferWasRequested()) { + mContainerActivity.onFileStateChanged(); // this is not working; FileDownloader won't do NOTHING at all until this method finishes, so + // checking the service to see if the file is downloading results in FALSE + } else { + Toast msg = Toast.makeText(getActivity(), R.string.sync_file_nothing_to_do_msg, Toast.LENGTH_LONG); + msg.show(); + if (mFile.isDown()) { + setButtonsForDown(); + + } else { + setButtonsForRemote(); + } + } + } + } }