import/export controller

This commit is contained in:
Tungstend 2023-07-03 20:30:41 +08:00
parent 96066c1f80
commit 2962a99628
9 changed files with 87 additions and 3 deletions

View File

@ -76,7 +76,7 @@ public class ControllerInfoDialog extends FCLDialog implements View.OnClickListe
if (!create) {
nameList.remove(controller.getName());
}
if (!OperatingSystem.isNameValid(editName.getText().toString())) {
if (!OperatingSystem.isNameValid(editName.getText().toString()) || editName.getText().toString().equals("Error")) {
Toast.makeText(getContext(), getContext().getString(R.string.control_info_name_invalid), Toast.LENGTH_SHORT).show();
} else if (nameList.contains(editName.getText().toString())) {
Toast.makeText(getContext(), getContext().getString(R.string.control_info_name_exist), Toast.LENGTH_SHORT).show();

View File

@ -2,18 +2,26 @@ package com.tungsten.fcl.ui.controller;
import static com.tungsten.fcl.util.FXUtils.onInvalidating;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.core.content.FileProvider;
import com.google.gson.GsonBuilder;
import com.tungsten.fcl.R;
import com.tungsten.fcl.activity.ControllerActivity;
import com.tungsten.fcl.setting.Controller;
import com.tungsten.fcl.setting.Controllers;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fclauncher.FCLPath;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
import com.tungsten.fclcore.fakefx.beans.property.BooleanProperty;
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty;
@ -21,13 +29,19 @@ import com.tungsten.fclcore.fakefx.beans.property.SimpleBooleanProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.Logging;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fcllibrary.browser.FileBrowser;
import com.tungsten.fcllibrary.browser.options.LibMode;
import com.tungsten.fcllibrary.browser.options.SelectionMode;
import com.tungsten.fcllibrary.component.ui.FCLCommonUI;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLTextView;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
public class ControllerUI extends FCLCommonUI implements View.OnClickListener {
@ -69,6 +83,7 @@ public class ControllerUI extends FCLCommonUI implements View.OnClickListener {
private LinearLayoutCompat importController;
private LinearLayoutCompat createController;
private FCLButton share;
private FCLButton editInfo;
private FCLButton editController;
@ -100,8 +115,10 @@ public class ControllerUI extends FCLCommonUI implements View.OnClickListener {
authorText.stringProperty().bind(Bindings.createStringBinding(() -> selectedController.get() == null ? "" : selectedController.get().getAuthor(), selectedController, refreshProperty));
descriptionText.stringProperty().bind(Bindings.createStringBinding(() -> selectedController.get() == null ? "" : selectedController.get().getDescription(), selectedController, refreshProperty));
share = findViewById(R.id.share);
editInfo = findViewById(R.id.edit_info);
editController = findViewById(R.id.edit_controller);
share.setOnClickListener(this);
editInfo.setOnClickListener(this);
editController.setOnClickListener(this);
@ -150,12 +167,44 @@ public class ControllerUI extends FCLCommonUI implements View.OnClickListener {
@Override
public void onClick(View view) {
if (view == importController) {
FileBrowser.Builder builder = new FileBrowser.Builder(getContext());
builder.setLibMode(LibMode.FILE_CHOOSER);
builder.setSelectionMode(SelectionMode.SINGLE_SELECTION);
ArrayList<String> suffix = new ArrayList<>();
suffix.add(".json");
builder.setSuffix(suffix);
builder.setTitle(getContext().getString(R.string.control_import));
builder.create().browse(getActivity(), RequestCodes.SELECT_CONTROLLER_CODE, ((requestCode, resultCode, data) -> {
if (requestCode == RequestCodes.SELECT_CONTROLLER_CODE && resultCode == Activity.RESULT_OK && data != null) {
String path = FileBrowser.getSelectedFiles(data).get(0);
try {
String content = FileUtils.readText(new File(path));
Controller controller = new GsonBuilder().setPrettyPrinting().create().fromJson(content, Controller.class);
if (controller.getName().equals("Error")) {
Toast.makeText(getContext(), getContext().getString(R.string.control_import_failed), Toast.LENGTH_SHORT).show();
} else {
addController(controller);
}
} catch (IOException e) {
Logging.LOG.log(Level.SEVERE, "Failed to import controller", e);
}
}
}));
}
if (view == createController) {
ControllerInfoDialog dialog = new ControllerInfoDialog(getContext(), true, new Controller(""), this::addController);
dialog.show();
}
if (view == share) {
Intent intent = new Intent(Intent.ACTION_SEND);
Uri uri = FileProvider.getUriForFile(getContext(), getContext().getString(com.tungsten.fcllibrary.R.string.file_browser_provider), new File(FCLPath.CONTROLLER_DIR, getSelectedController().getFileName()));
intent.setType(AndroidUtils.getMimeType(FCLPath.CONTROLLER_DIR + "/" + getSelectedController().getFileName()));
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
getActivity().startActivity(Intent.createChooser(intent, getContext().getString(R.string.control_share)));
}
if (view == editInfo) {
ControllerInfoDialog dialog = new ControllerInfoDialog(getContext(), false, selectedController.get(), (controller) -> changeControllerInfo(selectedController.get(), controller));
dialog.show();

View File

@ -10,9 +10,9 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -105,4 +105,19 @@ public class AndroidUtils {
}
}
@SuppressWarnings("resource")
public static String getMimeType(String filePath) {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
String mime = "*/*";
if (filePath != null) {
try {
mmr.setDataSource(filePath);
mime = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
} catch (RuntimeException e) {
return mime;
}
}
return mime;
}
}

View File

@ -17,4 +17,6 @@ public class RequestCodes {
public static final int SELECT_VERSION_ICON_CODE = 300;
public static final int SELECT_MODS_CODE = 350;
public static final int SELECT_CONTROLLER_CODE = 400;
}

View File

@ -249,6 +249,14 @@
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:ripple="true"
android:text="@string/control_share"
android:id="@+id/share"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginTop="10dp"
android:layout_width="match_parent"

View File

@ -90,6 +90,7 @@
<string name="control_delete">你确定要删除该布局吗?</string>
<string name="control_edit">编辑布局方案</string>
<string name="control_import">导入布局</string>
<string name="control_import_failed">导入布局失败!</string>
<string name="control_info_author">作者:</string>
<string name="control_info_description">描述:</string>
<string name="control_info_edit">编辑布局信息</string>
@ -100,6 +101,7 @@
<string name="control_info_version">版本:</string>
<string name="control_list">布局列表</string>
<string name="control_select">选择布局</string>
<string name="control_share">分享布局</string>
<string name="download_code_404">远程服务器不包含需要下载的文件: %s</string>
<string name="download_failed">下载失败: %1$s错误码%2$d</string>

View File

@ -3,4 +3,7 @@
<declare-styleable name="KeycodeView">
<attr name="keycode" format="integer"/>
</declare-styleable>
<declare-styleable name="LogWindow">
<attr name="auto_log_tint" format="boolean"/>
</declare-styleable>
</resources>

View File

@ -101,6 +101,7 @@
<string name="control_delete">Are you sure to delete this controller?</string>
<string name="control_edit">Edit Controller</string>
<string name="control_import">Import Controller</string>
<string name="control_import_failed">Failed to import controller!</string>
<string name="control_info_author">Author: </string>
<string name="control_info_description">Description: </string>
<string name="control_info_edit">Edit Controller Information</string>
@ -111,6 +112,7 @@
<string name="control_info_version">Version: </string>
<string name="control_list">Controller List</string>
<string name="control_select">Select Controller</string>
<string name="control_share">Share Controller</string>
<string name="download_code_404">File not found on the remote server: %s</string>
<string name="download_failed">Failed to download %1$s, response code: %2$d</string>

View File

@ -6,4 +6,7 @@
<cache-path
name="cache_path"
path="."/>
<files-path
name="files_path"
path="."/>
</paths>