From 0f4785e4217e648601670b9fe2d9694322a05060 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Mon, 9 Nov 2015 11:23:51 -0500 Subject: [PATCH] Update file attachment control --- .../astrid/activity/TaskEditFragment.java | 95 +------ .../todoroo/astrid/adapter/TaskAdapter.java | 9 +- .../todoroo/astrid/files/FilesControlSet.java | 252 +++++++++++------- .../res/drawable/file_type_background.xml | 11 - src/main/res/layout/control_set_files.xml | 37 ++- .../res/layout/control_set_files_dialog.xml | 23 -- src/main/res/layout/file_display_row.xml | 35 --- src/main/res/layout/file_row.xml | 47 ++-- src/main/res/menu/task_edit_fragment.xml | 5 - src/main/res/values/strings-premium.xml | 1 - src/main/res/values/strings.xml | 2 + 11 files changed, 211 insertions(+), 306 deletions(-) delete mode 100644 src/main/res/drawable/file_type_background.xml delete mode 100644 src/main/res/layout/control_set_files_dialog.xml delete mode 100644 src/main/res/layout/file_display_row.xml diff --git a/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java b/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java index 0cd80619c..d73351eec 100755 --- a/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java +++ b/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java @@ -26,8 +26,6 @@ import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; import android.view.WindowManager; -import android.webkit.MimeTypeMap; -import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; @@ -402,7 +400,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener { controls.add(timerControl); controlSetMap.put(getString(R.string.TEA_ctrl_timer_pref), timerControl); - filesControlSet = new FilesControlSet(preferences, taskAttachmentDao, getActivity(), dialogBuilder); + filesControlSet = new FilesControlSet(preferences, taskAttachmentDao, this, deviceInfo, actFmCameraModule); controls.add(filesControlSet); controlSetMap.put(getString(R.string.TEA_ctrl_files_pref), filesControlSet); @@ -560,9 +558,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener { loadItem(intent); synchronized (controls) { - if (!taskAttachmentDao.taskHasAttachments(model.getUuid())) { - filesControlSet.getView().setVisibility(View.GONE); - } for (TaskEditControlSet controlSet : controls) { controlSet.readFromTask(model); } @@ -731,101 +726,23 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener { .show(); } - private void startAttachFile() { - final List runnables = new ArrayList<>(); - List options = new ArrayList<>(); - - if (deviceInfo.hasCamera() || deviceInfo.hasGallery()) { - runnables.add(new Runnable() { - @Override - public void run() { - actFmCameraModule.showPictureLauncher(null); - } - }); - options.add(getString(R.string.file_add_picture)); - } - runnables.add(new Runnable() { - @Override - public void run() { - Intent attachFile = new Intent(getActivity(), FileExplore.class); - startActivityForResult(attachFile, REQUEST_CODE_ATTACH_FILE); - } - }); - options.add(getString(R.string.file_add_sdcard)); - - ArrayAdapter adapter = new ArrayAdapter<>(getActivity(), - android.R.layout.simple_spinner_dropdown_item, options.toArray(new String[options.size()])); - - DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface d, int which) { - runnables.get(which).run(); - } - }; - - // show a menu of available options - dialogBuilder.newDialog() - .setAdapter(adapter, listener) - .show() - .setOwnerActivity(getActivity()); - } - private void startRecordingAudio() { Intent recordAudio = new Intent(getActivity(), AACRecordingActivity.class); startActivityForResult(recordAudio, REQUEST_CODE_RECORD); } - private void attachFile(String file) { - File src = new File(file); - if (!src.exists()) { - Toast.makeText(getActivity(), R.string.file_err_copy, Toast.LENGTH_LONG).show(); - return; - } - - File dst = new File(preferences.getAttachmentsDirectory() + File.separator + src.getName()); - try { - AndroidUtilities.copyFile(src, dst); - } catch (Exception e) { - log.error(e.getMessage(), e); - Toast.makeText(getActivity(), R.string.file_err_copy, Toast.LENGTH_LONG).show(); - return; - } - - String path = dst.getAbsolutePath(); - String name = dst.getName(); - String extension = AndroidUtilities.getFileExtension(name); - - String type = TaskAttachment.FILE_TYPE_OTHER; - if (!TextUtils.isEmpty(extension)) { - MimeTypeMap map = MimeTypeMap.getSingleton(); - String guessedType = map.getMimeTypeFromExtension(extension); - if (!TextUtils.isEmpty(guessedType)) { - type = guessedType; - } - } - - createNewFileAttachment(path, name, type); - } - private void attachImage(Uri uri) { try { String path = getPathFromUri(getActivity(), uri); File file = new File(path); String extension = path.substring(path.lastIndexOf('.') + 1); - createNewFileAttachment(path, file.getName(), TaskAttachment.FILE_TYPE_IMAGE + extension); + filesControlSet.createNewFileAttachment(path, file.getName(), TaskAttachment.FILE_TYPE_IMAGE + extension); } catch (Exception e) { log.error(e.getMessage(), e); Toast.makeText(getActivity(), R.string.file_err_copy, Toast.LENGTH_LONG).show(); } } - private void createNewFileAttachment(String path, String fileName, String fileType) { - TaskAttachment attachment = TaskAttachment.createNewAttachment(model.getUuid(), path, fileName, fileType); - taskAttachmentDao.createNew(attachment); - filesControlSet.refreshMetadata(); - filesControlSet.getView().setVisibility(View.VISIBLE); - } - @Override public boolean onOptionsItemSelected(MenuItem item) { hideKeyboard(); @@ -837,9 +754,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener { case R.id.menu_discard: discardButtonClick(); return true; - case R.id.menu_attach: - startAttachFile(); - return true; case R.id.menu_record_note: startRecordingAudio(); return true; @@ -928,11 +842,10 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener { } else if (requestCode == REQUEST_CODE_RECORD && resultCode == Activity.RESULT_OK) { String recordedAudioPath = data.getStringExtra(AACRecordingActivity.RESULT_OUTFILE); String recordedAudioName = data.getStringExtra(AACRecordingActivity.RESULT_FILENAME); - createNewFileAttachment(recordedAudioPath, recordedAudioName, TaskAttachment.FILE_TYPE_AUDIO + "m4a"); //$NON-NLS-1$ + filesControlSet.createNewFileAttachment(recordedAudioPath, recordedAudioName, TaskAttachment.FILE_TYPE_AUDIO + "m4a"); //$NON-NLS-1$ } else if (requestCode == REQUEST_CODE_ATTACH_FILE && resultCode == Activity.RESULT_OK) { - attachFile(data.getStringExtra(FileExplore.RESULT_FILE_SELECTED)); + filesControlSet.attachFile(data.getStringExtra(FileExplore.RESULT_FILE_SELECTED)); } - actFmCameraModule.activityResult(requestCode, resultCode, data, new CameraResultCallback() { @Override public void handleCameraResult(Uri uri) { diff --git a/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java b/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java index 815d26e36..7efff93e3 100644 --- a/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java +++ b/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java @@ -158,7 +158,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { private final Map taskActionLoader = Collections.synchronizedMap(new HashMap()); public TaskAdapter(Context context, ActivityPreferences preferences, TaskAttachmentDao taskAttachmentDao, TaskService taskService, TaskListFragment fragment, - Cursor c, AtomicReference query, OnCompletedTaskListener onCompletedTaskListener, DialogBuilder dialogBuilder) { + Cursor c, AtomicReference query, OnCompletedTaskListener onCompletedTaskListener, + DialogBuilder dialogBuilder) { super(context, c, false); this.preferences = preferences; this.taskAttachmentDao = taskAttachmentDao; @@ -452,8 +453,10 @@ public class TaskAdapter extends CursorAdapter implements Filterable { } private void showFilesDialog(Task task) { - FilesControlSet filesControlSet = new FilesControlSet(preferences, taskAttachmentDao, - fragment.getActivity(), dialogBuilder); + FilesControlSet filesControlSet = new FilesControlSet( + preferences, taskAttachmentDao, + fragment, null, null); + filesControlSet.hideAddAttachmentButton(); filesControlSet.readFromTask(task); filesControlSet.getView().performClick(); } diff --git a/src/main/java/com/todoroo/astrid/files/FilesControlSet.java b/src/main/java/com/todoroo/astrid/files/FilesControlSet.java index 5cf70d425..68cf606d0 100644 --- a/src/main/java/com/todoroo/astrid/files/FilesControlSet.java +++ b/src/main/java/com/todoroo/astrid/files/FilesControlSet.java @@ -11,71 +11,104 @@ import android.content.DialogInterface; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; -import android.support.v4.app.FragmentActivity; +import android.support.v4.app.Fragment; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.webkit.MimeTypeMap; +import android.widget.ArrayAdapter; import android.widget.LinearLayout; -import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; import android.widget.Toast; import com.todoroo.andlib.data.Callback; import com.todoroo.andlib.utility.AndroidUtilities; -import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.astrid.actfm.ActFmCameraModule; +import com.todoroo.astrid.activity.TaskEditFragment; import com.todoroo.astrid.dao.TaskAttachmentDao; -import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.TaskAttachment; -import com.todoroo.astrid.ui.PopupControlSet; +import com.todoroo.astrid.helper.TaskEditControlSetBase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tasks.R; import org.tasks.dialogs.DialogBuilder; import org.tasks.preferences.ActivityPreferences; +import org.tasks.preferences.DeviceInfo; import java.io.File; import java.util.ArrayList; +import java.util.List; -public class FilesControlSet extends PopupControlSet { +public class FilesControlSet extends TaskEditControlSetBase { private static final Logger log = LoggerFactory.getLogger(FilesControlSet.class); private final ArrayList files = new ArrayList<>(); - private final LinearLayout fileDisplayList; private final LayoutInflater inflater; + private ActivityPreferences preferences; private final TaskAttachmentDao taskAttachmentDao; + private final Fragment fragment; + private final DeviceInfo deviceInfo; + private final ActFmCameraModule actFmCameraModule; private final DialogBuilder dialogBuilder; + private LinearLayout attachmentContainer; + private TextView addAttachment; public FilesControlSet(ActivityPreferences preferences, TaskAttachmentDao taskAttachmentDao, - FragmentActivity activity, DialogBuilder dialogBuilder) { - super(preferences, activity, R.layout.control_set_files_dialog, R.layout.control_set_files, R.string.TEA_control_files, dialogBuilder); + Fragment fragment, DeviceInfo deviceInfo, ActFmCameraModule actFmCameraModule) { + super(fragment.getActivity(), R.layout.control_set_files); + this.preferences = preferences; this.taskAttachmentDao = taskAttachmentDao; + this.fragment = fragment; + this.deviceInfo = deviceInfo; + this.actFmCameraModule = actFmCameraModule; this.dialogBuilder = new DialogBuilder(activity, preferences); - fileDisplayList = (LinearLayout) getView().findViewById(R.id.files_list); inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); } - @Override - protected void refreshDisplayView() { - fileDisplayList.removeAllViews(); - for (final TaskAttachment m : files) { - View fileRow = inflater.inflate(R.layout.file_display_row, null); - LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); - setUpFileRow(m, fileRow, fileDisplayList, lp); - } + private void addAttachment(TaskAttachment taskAttachment) { + View fileRow = inflater.inflate(R.layout.file_row, null); + fileRow.setTag(taskAttachment); + attachmentContainer.addView(fileRow); + addAttachment(taskAttachment, fileRow); } - @Override - public void readFromTask(Task task) { - super.readFromTask(task); - - refreshMetadata(); - refreshDisplayView(); + private void addAttachment(final TaskAttachment taskAttachment, final View fileRow) { + TextView nameView = (TextView) fileRow.findViewById(R.id.file_text); + nameView.setTextColor(themeColor); + String name = taskAttachment.getName(); + nameView.setText(name); + nameView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + showFile(taskAttachment); + } + }); + View clearFile = fileRow.findViewById(R.id.remove_file); + clearFile.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + dialogBuilder.newMessageDialog(R.string.premium_remove_file_confirm) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + taskAttachmentDao.delete(taskAttachment.getId()); + if (taskAttachment.containsNonNullValue(TaskAttachment.FILE_PATH)) { + File f = new File(taskAttachment.getFilePath()); + f.delete(); + } + files.remove(taskAttachment); + attachmentContainer.removeView(fileRow); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + }); } @Override @@ -112,12 +145,18 @@ public class FilesControlSet extends PopupControlSet { i--; } } - } } @Override protected void readFromTaskOnInitialize() { + attachmentContainer.removeAllViews(); + taskAttachmentDao.getAttachments(model.getUuid(), new Callback() { + @Override + public void apply(TaskAttachment entry) { + addAttachment(entry); + } + }); } @Override @@ -127,54 +166,18 @@ public class FilesControlSet extends PopupControlSet { @Override protected void afterInflate() { - LinearLayout fileList = (LinearLayout) getDialogView().findViewById(R.id.files_list); - final LinearLayout finalList = fileList; - fileList.removeAllViews(); - LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); - for (final TaskAttachment m : files) { - final View fileRow = inflater.inflate(R.layout.file_row, null); - - setUpFileRow(m, fileRow, fileList, lp); - View name = fileRow.findViewById(R.id.file_text); - View clearFile = fileRow.findViewById(R.id.remove_file); - - name.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - showFile(m); - } - }); + attachmentContainer = (LinearLayout) getView().findViewById(R.id.attachment_container); + addAttachment = (TextView) getView().findViewById(R.id.add_attachment); + addAttachment.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + startAttachFile(); + } + }); + } - clearFile.setVisibility(View.VISIBLE); - clearFile.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - dialogBuilder.newMessageDialog(R.string.premium_remove_file_confirm) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (RemoteModel.isValidUuid(m.getUUID())) { - // TODO: delete - m.setDeletedAt(DateUtilities.now()); - taskAttachmentDao.saveExisting(m); - } else { - taskAttachmentDao.delete(m.getId()); - } - - if (m.containsNonNullValue(TaskAttachment.FILE_PATH)) { - File f = new File(m.getFilePath()); - f.delete(); - } - files.remove(m); - refreshDisplayView(); - finalList.removeView(fileRow); - } - }) - .setNegativeButton(android.R.string.cancel, null) - .show(); - } - }); - } + public void hideAddAttachmentButton() { + addAttachment.setVisibility(View.GONE); } public interface PlaybackExceptionHandler { @@ -206,9 +209,14 @@ public class FilesControlSet extends PopupControlSet { } }); } else if (fileType.startsWith(TaskAttachment.FILE_TYPE_IMAGE)) { - activity.startActivity(new Intent(Intent.ACTION_VIEW) {{ - setDataAndType(Uri.fromFile(new File(filePath)), fileType); - }}); + try { + activity.startActivity(new Intent(Intent.ACTION_VIEW) {{ + setDataAndType(Uri.fromFile(new File(filePath)), fileType); + }}); + } catch(ActivityNotFoundException e) { + log.error(e.getMessage(), e); + Toast.makeText(activity, R.string.no_application_found, Toast.LENGTH_SHORT).show(); + } } else { String useType = fileType; if (fileType.equals(TaskAttachment.FILE_TYPE_OTHER)) { @@ -240,37 +248,83 @@ public class FilesControlSet extends PopupControlSet { } } - private void setUpFileRow(TaskAttachment m, View row, LinearLayout parent, LayoutParams lp) { - TextView nameView = (TextView) row.findViewById(R.id.file_text); - nameView.setTextColor(themeColor); - TextView typeView = (TextView) row.findViewById(R.id.file_type); - String name = getNameString(m); - String type = getTypeString(m.getName()); - nameView.setText(name); + private void startAttachFile() { + final List runnables = new ArrayList<>(); + List options = new ArrayList<>(); - if (TextUtils.isEmpty(type)) { - typeView.setVisibility(View.GONE); - } else { - typeView.setText(type); + if (deviceInfo.hasCamera() || deviceInfo.hasGallery()) { + runnables.add(new Runnable() { + @Override + public void run() { + actFmCameraModule.showPictureLauncher(null); + } + }); + options.add(activity.getString(R.string.file_add_picture)); } + runnables.add(new Runnable() { + @Override + public void run() { + Intent attachFile = new Intent(activity, FileExplore.class); + fragment.startActivityForResult(attachFile, TaskEditFragment.REQUEST_CODE_ATTACH_FILE); + } + }); + options.add(activity.getString(R.string.file_add_sdcard)); + + ArrayAdapter adapter = new ArrayAdapter<>( + activity, + android.R.layout.simple_spinner_dropdown_item, + options.toArray(new String[options.size()])); + + DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface d, int which) { + runnables.get(which).run(); + } + }; - parent.addView(row, lp); + // show a menu of available options + dialogBuilder.newDialog() + .setAdapter(adapter, listener) + .show() + .setOwnerActivity(activity); } - private String getNameString(TaskAttachment metadata) { - String name = metadata.getName(); - int extension = name.lastIndexOf('.'); - if (extension < 0) { - return name; + public void attachFile(String file) { + File src = new File(file); + if (!src.exists()) { + Toast.makeText(activity, R.string.file_err_copy, Toast.LENGTH_LONG).show(); + return; } - return name.substring(0, extension); - } - private String getTypeString(String name) { - int extension = name.lastIndexOf('.'); - if (extension < 0 || extension + 1 >= name.length()) { - return ""; + File dst = new File(preferences.getAttachmentsDirectory() + File.separator + src.getName()); + try { + AndroidUtilities.copyFile(src, dst); + } catch (Exception e) { + log.error(e.getMessage(), e); + Toast.makeText(activity, R.string.file_err_copy, Toast.LENGTH_LONG).show(); + return; + } + + String path = dst.getAbsolutePath(); + String name = dst.getName(); + String extension = AndroidUtilities.getFileExtension(name); + + String type = TaskAttachment.FILE_TYPE_OTHER; + if (!TextUtils.isEmpty(extension)) { + MimeTypeMap map = MimeTypeMap.getSingleton(); + String guessedType = map.getMimeTypeFromExtension(extension); + if (!TextUtils.isEmpty(guessedType)) { + type = guessedType; + } } - return name.substring(extension + 1).toUpperCase(); + + createNewFileAttachment(path, name, type); + } + + public void createNewFileAttachment(String path, String fileName, String fileType) { + TaskAttachment attachment = TaskAttachment.createNewAttachment(model.getUuid(), path, fileName, fileType); + taskAttachmentDao.createNew(attachment); + refreshMetadata(); + addAttachment(attachment); } } diff --git a/src/main/res/drawable/file_type_background.xml b/src/main/res/drawable/file_type_background.xml deleted file mode 100644 index effb09bda..000000000 --- a/src/main/res/drawable/file_type_background.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/src/main/res/layout/control_set_files.xml b/src/main/res/layout/control_set_files.xml index 2e160f493..5da58a1bf 100644 --- a/src/main/res/layout/control_set_files.xml +++ b/src/main/res/layout/control_set_files.xml @@ -4,11 +4,32 @@ ** See the file "LICENSE" for the full license governing this code. --> \ No newline at end of file + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + + + + + + + + + diff --git a/src/main/res/layout/control_set_files_dialog.xml b/src/main/res/layout/control_set_files_dialog.xml deleted file mode 100644 index 06a789d70..000000000 --- a/src/main/res/layout/control_set_files_dialog.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - diff --git a/src/main/res/layout/file_display_row.xml b/src/main/res/layout/file_display_row.xml deleted file mode 100644 index d9c1f3b4c..000000000 --- a/src/main/res/layout/file_display_row.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - diff --git a/src/main/res/layout/file_row.xml b/src/main/res/layout/file_row.xml index 2962dd76a..8231c64c3 100644 --- a/src/main/res/layout/file_row.xml +++ b/src/main/res/layout/file_row.xml @@ -4,46 +4,33 @@ ** See the file "LICENSE" for the full license governing this code. --> + android:paddingBottom="@dimen/task_edit_double_padding_top_bottom" + android:layout_marginBottom="@dimen/task_edit_double_padding_top_bottom"> - - + android:layout_weight="100" + android:textColor="?attr/asTextColor" /> + android:layout_gravity="center" + android:layout_weight="1" + android:clickable="true" + android:background="?attr/selectableItemBackgroundBorderless" + android:alpha="@dimen/drawer_icon_alpha" + android:paddingEnd="10dp" + android:paddingLeft="10dp" + android:paddingRight="10dp" + android:paddingStart="10dp" + android:src="@drawable/ic_cancel_24dp" + android:tint="?attr/icon_tint" /> diff --git a/src/main/res/menu/task_edit_fragment.xml b/src/main/res/menu/task_edit_fragment.xml index c61fff89f..4a989547b 100644 --- a/src/main/res/menu/task_edit_fragment.xml +++ b/src/main/res/menu/task_edit_fragment.xml @@ -8,11 +8,6 @@ android:icon="@drawable/ic_save_24dp" android:visible="false" tasks:showAsAction="ifRoom"/> - - Attach a file Record a note Are you sure? Cannot be undone diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 7c0269ccf..d8bfbf467 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -121,6 +121,8 @@ Reverse %s Tasks Get Plug-ins + No application found to open attachment + Add attachment