diff options
Diffstat (limited to 'src/com/lamerman/FileDialog.java')
| -rw-r--r-- | src/com/lamerman/FileDialog.java | 389 | 
1 files changed, 389 insertions, 0 deletions
diff --git a/src/com/lamerman/FileDialog.java b/src/com/lamerman/FileDialog.java new file mode 100644 index 00000000..821b1fbf --- /dev/null +++ b/src/com/lamerman/FileDialog.java @@ -0,0 +1,389 @@ +package com.lamerman; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.TreeMap; + +import de.blinkt.openvpn.R; + +import android.app.AlertDialog; +import android.app.ListActivity; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.SimpleAdapter; +import android.widget.TextView; + +/** + * Activity para escolha de arquivos/diretorios. + *  + * @author android + *  + */ +public class FileDialog extends ListActivity { + +	/** +	 * Chave de um item da lista de paths. +	 */ +	private static final String ITEM_KEY = "key"; + +	/** +	 * Imagem de um item da lista de paths (diretorio ou arquivo). +	 */ +	private static final String ITEM_IMAGE = "image"; + +	/** +	 * Diretorio raiz. +	 */ +	private static final String ROOT = "/"; + +	/** +	 * Parametro de entrada da Activity: path inicial. Padrao: ROOT. +	 */ +	public static final String START_PATH = "START_PATH"; + +	/** +	 * Parametro de entrada da Activity: filtro de formatos de arquivos. Padrao: +	 * null. +	 */ +	public static final String FORMAT_FILTER = "FORMAT_FILTER"; + +	/** +	 * Parametro de saida da Activity: path escolhido. Padrao: null. +	 */ +	public static final String RESULT_PATH = "RESULT_PATH"; + +	/** +	 * Parametro de entrada da Activity: tipo de selecao: pode criar novos paths +	 * ou nao. Padrao: nao permite. +	 *  +	 * @see {@link SelectionMode} +	 */ +	public static final String SELECTION_MODE = "SELECTION_MODE"; + +	/** +	 * Parametro de entrada da Activity: se e permitido escolher diretorios. +	 * Padrao: falso. +	 */ +	public static final String CAN_SELECT_DIR = "CAN_SELECT_DIR"; + +	private List<String> path = null; +	private TextView myPath; +	private EditText mFileName; +	private ArrayList<HashMap<String, Object>> mList; + +	private Button selectButton; + +	private LinearLayout layoutSelect; +	private LinearLayout layoutCreate; +	private InputMethodManager inputManager; +	private String parentPath; +	private String currentPath = ROOT; + +	private int selectionMode = SelectionMode.MODE_CREATE; + +	private String[] formatFilter = null; + +	private boolean canSelectDir = false; + +	private File selectedFile; +	private HashMap<String, Integer> lastPositions = new HashMap<String, Integer>(); + +	/** +	 * Called when the activity is first created. Configura todos os parametros +	 * de entrada e das VIEWS.. +	 */ +	@Override +	public void onCreate(Bundle savedInstanceState) { +		super.onCreate(savedInstanceState); +		setResult(RESULT_CANCELED, getIntent()); + +		setContentView(R.layout.file_dialog_main); +		myPath = (TextView) findViewById(R.id.path); +		mFileName = (EditText) findViewById(R.id.fdEditTextFile); + +		inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + +		selectButton = (Button) findViewById(R.id.fdButtonSelect); +		selectButton.setEnabled(false); +		selectButton.setOnClickListener(new OnClickListener() { + +			@Override +			public void onClick(View v) { +				if (selectedFile != null) { +					getIntent().putExtra(RESULT_PATH, selectedFile.getPath()); +					setResult(RESULT_OK, getIntent()); +					finish(); +				} +			} +		}); + +		final Button newButton = (Button) findViewById(R.id.fdButtonNew); +		newButton.setOnClickListener(new OnClickListener() { + +			@Override +			public void onClick(View v) { +				setCreateVisible(v); + +				mFileName.setText(""); +				mFileName.requestFocus(); +			} +		}); + +		selectionMode = getIntent().getIntExtra(SELECTION_MODE, SelectionMode.MODE_CREATE); + +		formatFilter = getIntent().getStringArrayExtra(FORMAT_FILTER); + +		canSelectDir = getIntent().getBooleanExtra(CAN_SELECT_DIR, false); + +		if (selectionMode == SelectionMode.MODE_OPEN) { +			newButton.setEnabled(false); +			newButton.setVisibility(View.GONE); +		} + +		layoutSelect = (LinearLayout) findViewById(R.id.fdLinearLayoutSelect); +		layoutCreate = (LinearLayout) findViewById(R.id.fdLinearLayoutCreate); +		layoutCreate.setVisibility(View.GONE); + +		final Button cancelButton = (Button) findViewById(R.id.fdButtonCancel); +		cancelButton.setOnClickListener(new OnClickListener() { + +			@Override +			public void onClick(View v) { +				setSelectVisible(v); +			} + +		}); +		final Button createButton = (Button) findViewById(R.id.fdButtonCreate); +		createButton.setOnClickListener(new OnClickListener() { + +			@Override +			public void onClick(View v) { +				if (mFileName.getText().length() > 0) { +					getIntent().putExtra(RESULT_PATH, currentPath + "/" + mFileName.getText()); +					setResult(RESULT_OK, getIntent()); +					finish(); +				} +			} +		}); + +		String startPath = getIntent().getStringExtra(START_PATH); +		startPath = startPath != null ? startPath : ROOT; +		if (canSelectDir) { +			File file = new File(startPath); +			selectedFile = file; +			selectButton.setEnabled(true); +		} +		getDir(startPath); +	} + +	private void getDir(String dirPath) { + +		boolean useAutoSelection = dirPath.length() < currentPath.length(); + +		Integer position = lastPositions.get(parentPath); + +		getDirImpl(dirPath); + +		if (position != null && useAutoSelection) { +			getListView().setSelection(position); +		} + +	} + +	/** +	 * Monta a estrutura de arquivos e diretorios filhos do diretorio fornecido. +	 *  +	 * @param dirPath +	 *            Diretorio pai. +	 */ +	private void getDirImpl(final String dirPath) { + +		currentPath = dirPath; + +		final List<String> item = new ArrayList<String>(); +		path = new ArrayList<String>(); +		mList = new ArrayList<HashMap<String, Object>>(); + +		File f = new File(currentPath); +		File[] files = f.listFiles(); +		if (files == null) { +			currentPath = ROOT; +			f = new File(currentPath); +			files = f.listFiles(); +		} +		myPath.setText(getText(R.string.location) + ": " + currentPath); + +		if (!currentPath.equals(ROOT)) { + +			item.add(ROOT); +			addItem(ROOT, R.drawable.folder); +			path.add(ROOT); + +			item.add("../"); +			addItem("../", R.drawable.folder); +			path.add(f.getParent()); +			parentPath = f.getParent(); + +		} + +		TreeMap<String, String> dirsMap = new TreeMap<String, String>(); +		TreeMap<String, String> dirsPathMap = new TreeMap<String, String>(); +		TreeMap<String, String> filesMap = new TreeMap<String, String>(); +		TreeMap<String, String> filesPathMap = new TreeMap<String, String>(); +		for (File file : files) { +			if (file.isDirectory()) { +				String dirName = file.getName(); +				dirsMap.put(dirName, dirName); +				dirsPathMap.put(dirName, file.getPath()); +			} else { +				final String fileName = file.getName(); +				final String fileNameLwr = fileName.toLowerCase(); +				// se ha um filtro de formatos, utiliza-o +				if (formatFilter != null) { +					boolean contains = false; +					for (int i = 0; i < formatFilter.length; i++) { +						final String formatLwr = formatFilter[i].toLowerCase(); +						if (fileNameLwr.endsWith(formatLwr)) { +							contains = true; +							break; +						} +					} +					if (contains) { +						filesMap.put(fileName, fileName); +						filesPathMap.put(fileName, file.getPath()); +					} +					// senao, adiciona todos os arquivos +				} else { +					filesMap.put(fileName, fileName); +					filesPathMap.put(fileName, file.getPath()); +				} +			} +		} +		item.addAll(dirsMap.tailMap("").values()); +		item.addAll(filesMap.tailMap("").values()); +		path.addAll(dirsPathMap.tailMap("").values()); +		path.addAll(filesPathMap.tailMap("").values()); + +		SimpleAdapter fileList = new SimpleAdapter(this, mList, R.layout.file_dialog_row, new String[] { +				ITEM_KEY, ITEM_IMAGE }, new int[] { R.id.fdrowtext, R.id.fdrowimage }); + +		for (String dir : dirsMap.tailMap("").values()) { +			addItem(dir, R.drawable.folder); +		} + +		for (String file : filesMap.tailMap("").values()) { +			addItem(file, R.drawable.file); +		} + +		fileList.notifyDataSetChanged(); + +		setListAdapter(fileList); + +	} + +	private void addItem(String fileName, int imageId) { +		HashMap<String, Object> item = new HashMap<String, Object>(); +		item.put(ITEM_KEY, fileName); +		item.put(ITEM_IMAGE, imageId); +		mList.add(item); +	} + +	/** +	 * Quando clica no item da lista, deve-se: 1) Se for diretorio, abre seus +	 * arquivos filhos; 2) Se puder escolher diretorio, define-o como sendo o +	 * path escolhido. 3) Se for arquivo, define-o como path escolhido. 4) Ativa +	 * botao de selecao. +	 */ +	@Override +	protected void onListItemClick(ListView l, View v, int position, long id) { + +		File file = new File(path.get(position)); + +		setSelectVisible(v); + +		if (file.isDirectory()) { +			selectButton.setEnabled(false); +			if (file.canRead()) { +				lastPositions.put(currentPath, position); +				getDir(path.get(position)); +				if (canSelectDir) { +					selectedFile = file; +					v.setSelected(true); +					selectButton.setEnabled(true); +				} +			} else { +				new AlertDialog.Builder(this).setIcon(R.drawable.icon) +						.setTitle("[" + file.getName() + "] " + getText(R.string.cant_read_folder)) +						.setPositiveButton("OK", new DialogInterface.OnClickListener() { + +							@Override +							public void onClick(DialogInterface dialog, int which) { + +							} +						}).show(); +			} +		} else { +			selectedFile = file; +			v.setSelected(true); +			selectButton.setEnabled(true); +		} +	} + +	@Override +	public boolean onKeyDown(int keyCode, KeyEvent event) { +		if ((keyCode == KeyEvent.KEYCODE_BACK)) { +			selectButton.setEnabled(false); + +			if (layoutCreate.getVisibility() == View.VISIBLE) { +				layoutCreate.setVisibility(View.GONE); +				layoutSelect.setVisibility(View.VISIBLE); +			} else { +				if (!currentPath.equals(ROOT)) { +					getDir(parentPath); +				} else { +					return super.onKeyDown(keyCode, event); +				} +			} + +			return true; +		} else { +			return super.onKeyDown(keyCode, event); +		} +	} + +	/** +	 * Define se o botao de CREATE e visivel. +	 *  +	 * @param v +	 */ +	private void setCreateVisible(View v) { +		layoutCreate.setVisibility(View.VISIBLE); +		layoutSelect.setVisibility(View.GONE); + +		inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0); +		selectButton.setEnabled(false); +	} + +	/** +	 * Define se o botao de SELECT e visivel. +	 *  +	 * @param v +	 */ +	private void setSelectVisible(View v) { +		layoutCreate.setVisibility(View.GONE); +		layoutSelect.setVisibility(View.VISIBLE); + +		inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0); +		selectButton.setEnabled(false); +	} +}  | 
