Add file browser support when setting UCI options

For string UCI options containing "file" or "path" in their names, add
a button that opens a file browser to set the value of the option.

The browse button is only available if "OI file manager" or a
compatible app is installed. The button is not available for network
engines because there is no way to browse the remote filesystem where
the network engine runs.
This commit is contained in:
Peter Osterlund 2020-03-15 14:29:44 +01:00
parent 9880654006
commit eaced74b3a
4 changed files with 107 additions and 0 deletions

View File

@ -3181,6 +3181,9 @@ public class DroidFish extends Activity
if (uciOpts != null) { if (uciOpts != null) {
i.putExtra("org.petero.droidfish.ucioptions", uciOpts); i.putExtra("org.petero.droidfish.ucioptions", uciOpts);
i.putExtra("org.petero.droidfish.enginename", engineTitleText.getText()); i.putExtra("org.petero.droidfish.enginename", engineTitleText.getText());
i.putExtra("org.petero.droidfish.workDir", engineOptions.workDir);
boolean localEngine = engineOptions.networkID.isEmpty();
i.putExtra("org.petero.droidfish.localEngine", localEngine);
startActivityForResult(i, RESULT_EDITOPTIONS); startActivityForResult(i, RESULT_EDITOPTIONS);
} }
} }

View File

@ -19,24 +19,39 @@
package org.petero.droidfish.activities; package org.petero.droidfish.activities;
import android.app.Activity; import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener; import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import com.caverock.androidsvg.SVG;
import com.caverock.androidsvg.SVGParseException;
import androidx.databinding.DataBindingUtil; import androidx.databinding.DataBindingUtil;
import org.petero.droidfish.DroidFishApp; import org.petero.droidfish.DroidFishApp;
import org.petero.droidfish.FileUtil;
import org.petero.droidfish.R; import org.petero.droidfish.R;
import org.petero.droidfish.SVGPictureDrawable;
import org.petero.droidfish.Util; import org.petero.droidfish.Util;
import org.petero.droidfish.databinding.EditoptionsBinding; import org.petero.droidfish.databinding.EditoptionsBinding;
import org.petero.droidfish.databinding.UciOptionButtonBinding; import org.petero.droidfish.databinding.UciOptionButtonBinding;
@ -46,6 +61,7 @@ import org.petero.droidfish.databinding.UciOptionSpinBinding;
import org.petero.droidfish.databinding.UciOptionStringBinding; import org.petero.droidfish.databinding.UciOptionStringBinding;
import org.petero.droidfish.engine.UCIOptions; import org.petero.droidfish.engine.UCIOptions;
import java.io.File;
import java.util.Locale; import java.util.Locale;
import java.util.TreeMap; import java.util.TreeMap;
@ -55,6 +71,11 @@ import java.util.TreeMap;
public class EditOptions extends Activity { public class EditOptions extends Activity {
private UCIOptions uciOpts = null; private UCIOptions uciOpts = null;
private String engineName = ""; private String engineName = "";
private String workDir = "";
private boolean hasBrowser = false; // True if OI file manager available
private UCIOptions.StringOption currentStringOption; // Option that triggered file browsing
private EditText currentTextField;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -66,7 +87,13 @@ public class EditOptions extends Activity {
Intent i = getIntent(); Intent i = getIntent();
uciOpts = (UCIOptions) i.getSerializableExtra("org.petero.droidfish.ucioptions"); uciOpts = (UCIOptions) i.getSerializableExtra("org.petero.droidfish.ucioptions");
engineName = (String) i.getSerializableExtra("org.petero.droidfish.enginename"); engineName = (String) i.getSerializableExtra("org.petero.droidfish.enginename");
workDir = (String) i.getSerializableExtra("org.petero.droidfish.workDir");
hasBrowser = (Boolean) i.getSerializableExtra("org.petero.droidfish.localEngine");
if (uciOpts != null) { if (uciOpts != null) {
if (hasBrowser) {
Intent browser = new Intent("org.openintents.action.PICK_FILE");
hasBrowser = browser.resolveActivity(getPackageManager()) != null;
}
initUI(); initUI();
} else { } else {
setResult(RESULT_CANCELED); setResult(RESULT_CANCELED);
@ -238,6 +265,12 @@ public class EditOptions extends Activity {
so.set(s.toString()); so.set(s.toString());
} }
}); });
boolean isFileOption = hasBrowser && (o.name.toLowerCase().contains("file") ||
o.name.toLowerCase().contains("path"));
setBrowseImage(holder.eoBrowse, isFileOption);
holder.eoBrowse.setOnClickListener(view -> {
browseFile(so, holder.eoValue);
});
return holder.getRoot(); return holder.getRoot();
} }
default: default:
@ -245,6 +278,71 @@ public class EditOptions extends Activity {
} }
} }
private void setBrowseImage(ImageButton button, boolean visible) {
button.setVisibility(visible ? View.VISIBLE : View.GONE);
Resources r = getResources();
try {
SVG svg = SVG.getFromResource(r, R.raw.open_last_file);
button.setBackgroundDrawable(new SVGPictureDrawable(svg));
} catch (SVGParseException ignore) {
}
try {
SVG touched = SVG.getFromResource(r, R.raw.touch);
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[]{android.R.attr.state_pressed}, new SVGPictureDrawable(touched));
button.setImageDrawable(sld);
} catch (SVGParseException ignore) {
}
int bWidth = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
36, r.getDisplayMetrics()));
int bHeight = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
32, r.getDisplayMetrics()));
ViewGroup.LayoutParams lp = button.getLayoutParams();
lp.width = bWidth;
lp.height = bHeight;
button.setLayoutParams(lp);
button.setPadding(0,0,0,0);
button.setScaleType(ImageView.ScaleType.FIT_XY);
}
private void browseFile(UCIOptions.StringOption so, EditText textField) {
String currentFile = so.getStringValue();
String sep = File.separator;
if (!currentFile.contains(sep))
currentFile = workDir + sep + currentFile;
Intent i = new Intent("org.openintents.action.PICK_FILE");
i.setData(Uri.fromFile(new File(currentFile)));
i.putExtra("org.openintents.extra.TITLE", getString(R.string.select_file));
try {
startActivityForResult(i, RESULT_OI_SELECT_FILE);
currentStringOption = so;
currentTextField = textField;
} catch (ActivityNotFoundException ignore) {
}
}
static private final int RESULT_OI_SELECT_FILE = 0;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case RESULT_OI_SELECT_FILE:
if (resultCode == RESULT_OK && currentStringOption != null) {
String pathName = FileUtil.getFilePathFromUri(data.getData());
if (pathName != null && currentTextField != null) {
if (currentStringOption.set(pathName))
currentTextField.setText(pathName);
}
}
currentStringOption = null;
currentTextField = null;
break;
}
}
private void sendBackResult() { private void sendBackResult() {
if (uciOpts != null) { if (uciOpts != null) {
TreeMap<String, String> uciMap = new TreeMap<>(); TreeMap<String, String> uciMap = new TreeMap<>();

View File

@ -16,5 +16,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:inputType="text" /> android:inputType="text" />
<ImageButton
android:id="@+id/eo_browse"
android:layout_width="36dp"
android:layout_height="32dp" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@ -81,6 +81,7 @@ If you are running on battery power, it is recommended that you change settings
<string name="select_pgn_file">Open PGN file</string> <string name="select_pgn_file">Open PGN file</string>
<string name="select_pgn_file_save">Save to PGN file</string> <string name="select_pgn_file_save">Save to PGN file</string>
<string name="select_fen_file">Open FEN/EPD file</string> <string name="select_fen_file">Open FEN/EPD file</string>
<string name="select_file">Select file</string>
<string name="pgn_load">Load</string> <string name="pgn_load">Load</string>
<string name="pgn_save">Save</string> <string name="pgn_save">Save</string>
<string name="reading_pgn_file">Reading PGN file…</string> <string name="reading_pgn_file">Reading PGN file…</string>