/* * Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * * This file is part of Loop Habit Tracker. * * Loop Habit Tracker 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. * * Loop Habit Tracker 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 org.isoron.uhabits.activities.common.dialogs; import android.content.*; import android.support.annotation.*; import android.support.v7.app.*; import android.view.*; import android.view.WindowManager.*; import android.widget.*; import com.google.auto.factory.*; import org.isoron.uhabits.activities.*; import java.io.*; import java.util.*; /** * Dialog that allows the user to pick a file. */ @AutoFactory(allowSubclasses = true) public class FilePickerDialog implements AdapterView.OnItemClickListener { private static final String PARENT_DIR = ".."; private final Context context; private ListView list; private AppCompatDialog dialog; private File currentPath; private OnFileSelectedListener listener; public FilePickerDialog(@Provided @ActivityContext Context context, File initialDirectory) { this.context = context; list = new ListView(context); list.setOnItemClickListener(this); dialog = new AppCompatDialog(context); dialog.setContentView(list); dialog .getWindow() .setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); navigateTo(initialDirectory); } public AppCompatDialog getDialog() { return dialog; } @Override public void onItemClick(AdapterView<?> parent, View view, int which, long id) { String filename = (String) list.getItemAtPosition(which); File file; if (filename.equals(PARENT_DIR)) file = currentPath.getParentFile(); else file = new File(currentPath, filename); if (file.isDirectory()) { navigateTo(file); } else { if (listener != null) listener.onFileSelected(file); dialog.dismiss(); } } public void setListener(OnFileSelectedListener listener) { this.listener = listener; } public void show() { dialog.show(); } @NonNull private String[] getFileList(File path, File[] dirs, File[] files) { int count = 0; int length = dirs.length + files.length; String[] fileList; if (path.getParentFile() == null || !path.getParentFile().canRead()) { fileList = new String[length]; } else { fileList = new String[length + 1]; fileList[count++] = PARENT_DIR; } Arrays.sort(dirs); Arrays.sort(files); for (File dir : dirs) fileList[count++] = dir.getName(); for (File file : files) fileList[count++] = file.getName(); return fileList; } private void navigateTo(File path) { if (!path.exists()) return; File[] dirs = path.listFiles(new ReadableDirFilter()); File[] files = path.listFiles(new RegularReadableFileFilter()); if (dirs == null || files == null) return; this.currentPath = path; dialog.setTitle(currentPath.getPath()); list.setAdapter(new FilePickerAdapter(getFileList(path, dirs, files))); } public interface OnFileSelectedListener { void onFileSelected(File file); } private static class ReadableDirFilter implements FileFilter { @Override public boolean accept(File file) { return (file.isDirectory() && file.canRead()); } } private class FilePickerAdapter extends ArrayAdapter<String> { public FilePickerAdapter(@NonNull String[] fileList) { super(FilePickerDialog.this.context, android.R.layout.simple_list_item_1, fileList); } @Override public View getView(int pos, View view, ViewGroup parent) { view = super.getView(pos, view, parent); TextView tv = (TextView) view; tv.setSingleLine(true); return view; } } private class RegularReadableFileFilter implements FileFilter { @Override public boolean accept(File file) { return !file.isDirectory() && file.canRead(); } } }