Mercurial > hg > ccmiandroid
view src/uk/ac/qmul/eecs/ccmi/activities/FileSelectorActivity.java @ 0:e0ee6ac3a45f
first import
author | Fiore Martin <fiore@eecs.qmul.ac.uk> |
---|---|
date | Thu, 13 Dec 2012 20:00:21 +0000 |
parents | |
children |
line wrap: on
line source
/* CCmI Diagram Editor for Android Copyright (C) 2012 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) 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 (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.qmul.eecs.ccmi.activities; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.List; import uk.ac.qmul.eecs.ccmi.accessibility.AccessibilityService.SoundEvent; import uk.ac.qmul.eecs.ccmi.accessibility.AccessibilityService; import uk.ac.qmul.eecs.ccmi.accessibility.AccessibleDialogBuilder; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.support.v4.app.DialogFragment; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.TextView; /** * An abstract activity for file selection. * * The file system is shown as follows: the current directory is displayed * on a the header and all the files or folder contained in it are displayed in a list view. Clicking on a list item * will only take effect if the item is a directory. The selected directory will become the current directory. * In order to select the parent directory a click on the back button is needed. * * Being an {@code AccessibleActivity} the view can be explored though sound and haptics by hovering on it. * in order to scroll the list a double-finger scroll is required or, if the device does not support multitouch, a * scroll button will appear on the bottom for scrolling. * */ public abstract class FileSelectorActivity extends AccessibleActivity implements OnItemClickListener, OnItemLongClickListener { private File[] currentFileList; private File currentFile; private FileFilter fileFilter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); list.setOnItemClickListener(this); list.setOnItemLongClickListener(this); final CharSequence extension = getIntent().getCharSequenceExtra("extension"); fileFilter = new FileFilter() { /* only accepts directories and .ccmi files */ public boolean accept(File file) { if (file.isDirectory()) { return true; } if(extension == null) return true; else return file.getName().endsWith(extension.toString()); } }; update(new File(Environment.getExternalStorageDirectory().getPath())); } /* false if new list is empty, true otherwise */ private boolean update(File file) { currentFile = file; currentFileList = currentFile.listFiles(fileFilter); setHeaderText(currentFile.getName()); List<String> names = new ArrayList<String>(currentFileList.length); for (int i = 0; i < currentFileList.length; i ++) { String fileName = currentFileList[i].getName(); if (currentFileList[i].isDirectory()) { fileName = "/" + fileName; } names.add(fileName); } list.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item_1, names)); return !names.isEmpty(); } @Override public void onItemClick(AdapterView<?> av, View v, int position, long id) { // the first thing in list is parent directory, so we must offset it File selectedFile = currentFileList[position]; if (selectedFile.isDirectory()) { if(selectedFile.listFiles(fileFilter).length == 0){ accessibilityService.playSound(SoundEvent.V_ERROR); accessibilityService.speak("Directory empty"); } boolean anyItems = update(selectedFile); accessibilityService.playSound(AccessibilityService.SoundEvent.V_EXPAND); if(anyItems) accessibilityService.speak("Displaying " + getHeaderText()); else accessibilityService.speak("Displaying " + getHeaderText()+". Empty"); }else{ accessibilityService.playSound(SoundEvent.V_ERROR); } } /** * To be implemented by subclasses. The long click represent the trigger of an operation on the selected file. */ @Override public abstract boolean onItemLongClick(AdapterView<?> av, View v, int position, long id); /** * On pressing the back button, the parent of the current directory will be displayed. */ @Override public void onBackPressed() { if(currentFile.getAbsolutePath().equals(Environment.getExternalStorageDirectory().getPath())){ setResult(RESULT_CANCELED); super.onBackPressed(); // finish the activity return; } File parent = currentFile.getParentFile(); update(parent); accessibilityService.playSound(SoundEvent.V_COLLAPSE); accessibilityService.speak("Displaying "+getHeaderText()); } /** * A {@code FileSelectorActivity} for opening a file. A long click on an item will open a confirmation dialog * to open the file. If the user confirms, the activity will finish and set a result intent with the Uri * of the opened file. */ public static class Open extends FileSelectorActivity { /** * Displays a confirmation dialog to open the file */ @Override public boolean onItemLongClick(AdapterView<?> av, View v, int position, long id) { final File selectedFile = super.currentFileList[position]; if(selectedFile.isDirectory()){ accessibilityService.playSound(SoundEvent.V_ERROR); return true; } dialogBuilder.displayDialog(R.layout.alert_dialog_confirmation, "Do you want to Open File "+(((TextView)v).getText())+" ?", new AccessibleDialogBuilder.ButtonClickListener(){ @Override public void onClick(View v, DialogFragment dialogFragment, String dialogTag){ if("YES".equals(v.getTag())){ // YES dialogFragment.dismiss(); Intent resultIntent = new Intent(); resultIntent.setData(Uri.fromFile(selectedFile)); setResult(RESULT_OK, resultIntent); finish(); }else{ // NO dialogFragment.dismiss(); accessibilityService.playSound(SoundEvent.V_CANCEL); accessibilityService.speak(getHeaderText().toString()); } } }); return true; } @Override public String getName(){ return "Select File to Open"; } } /** * A {@code FileSelectorActivity} for saving a file. A long click on an item will open a text dialog * to enter the name of the file to save. If the user clicks on a file list item, the text field will * be filled with the name thereof. */ public static class Save extends FileSelectorActivity { /** * When the user long-clicks on an item a text dialog for the user to enter the file name appears. */ @Override public boolean onItemLongClick(AdapterView<?> av, View v, int position, long id) { final File selectedFile = super.currentFileList[position]; final String text = selectedFile.isDirectory() ? "" : selectedFile.getName(); dialogBuilder.displayTextDialog("Enter File name ", text, new AccessibleDialogBuilder.ButtonClickListener(){ @Override public void onClick(View v, DialogFragment dialogFragment, String dialogTag) { Object buttonTag = v.getTag(); if("OK".equals(buttonTag)){ EditText editText = (EditText)dialogFragment.getDialog().findViewById(R.id.text_edit); String text = editText.getText().toString().trim(); if(text.length() == 0){ accessibilityService.playSound(SoundEvent.V_ERROR); accessibilityService.speak("File name cannot be empty"); return; } /* if the selected file was a directory, then concat it with the text entered by the user * * if it was a file, then concat the directory where the file was with the text entered by the user * * In the latter the user can overwrite a file just by clicking OK without entering any text */ Uri dir = selectedFile.isDirectory() ? Uri.fromFile(selectedFile) : Uri.fromFile(selectedFile.getParentFile()); Intent resultIntent = new Intent(); resultIntent.setData(Uri.withAppendedPath(dir, text)); setResult(RESULT_OK, resultIntent); finish(); }else{ dialogFragment.dismiss(); accessibilityService.playSound(SoundEvent.V_CANCEL); accessibilityService.speak(getHeaderText().toString()); } } }); return false; } public String getName(){ return "Select File to Save"; } } }