fix: import sample or create file not working. add: edit icon of view sample activity

This commit is contained in:
hyb1996 committed 2017-08-01 10:48:19 +08:00
1 parent f037a642fd
commit 08419afc3d
13 files changed
+615 -234

No files matched your search

+228
View File
@@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
</value>
</option>
<option name="RIGHT_MARGIN" value="100" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
</AndroidXmlCodeStyleSettings>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" />
<pair source="c" header="h" />
</extensions>
</Objective-C-extensions>
<XML>
<option name="XML_KEEP_LINE_BREAKS" value="false" />
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
</XML>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</value>
</option>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
</component>
</project>
+3
View File
@@ -118,6 +118,9 @@ dependencies {
compile 'com.yqritc:recyclerview-flexibledivider:1.4.0' compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'
compile 'com.ashokvarma.android:bottom-navigation-bar:2.0.1' compile 'com.ashokvarma.android:bottom-navigation-bar:2.0.1'
compile 'com.wang.avi:library:2.1.3' compile 'com.wang.avi:library:2.1.3'
compile "io.reactivex.rxjava2:rxjava:2.1.0"
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Tasker Plugin // Tasker Plugin
compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:[4.0.2, 5.0[' compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:[4.0.2, 5.0['
compile 'com.android.volley:volley:1.0.0' compile 'com.android.volley:volley:1.0.0'
@@ -0,0 +1,252 @@
package com.stardust.scriptdroid.ui.common;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.DrawerLayout;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.pio.PFile;
import com.stardust.pio.UncheckedIOException;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.Scripts;
import com.stardust.scriptdroid.script.StorageScriptProvider;
import com.stardust.scriptdroid.script.sample.Sample;
import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.scriptdroid.ui.main.MainActivity;
import com.stardust.scriptdroid.ui.main.script_list.MyScriptListFragment;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.UnderuseExecutors;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
/**
* Created by Stardust on 2017/7/31.
*/
public class ScriptOperations {
private Activity mActivity;
private View mView;
private ScriptFile mCurrentDirectory;
public ScriptOperations(Activity activity, View view, ScriptFile currentDirectory) {
mActivity = activity;
mView = view;
mCurrentDirectory = currentDirectory;
}
public ScriptOperations(Activity activity, View view) {
this(activity, view, MyScriptListFragment.getCurrentDirectory());
}
public void newScriptFileForScript(final String script) {
showFileNameInputDialog("")
.subscribe(new Consumer<String>() {
@Override
public void accept(@io.reactivex.annotations.NonNull String input) throws Exception {
createScriptFile(getCurrentDirectoryPath() + input + ".js", script);
}
});
}
private String getCurrentDirectoryPath() {
return getCurrentDirectory().getPath() + "/";
}
private ScriptFile getCurrentDirectory() {
return mCurrentDirectory;
}
public void createScriptFile(String path, String script) {
if (PFile.createIfNotExists(path)) {
if (script != null) {
try {
PFile.write(path, script);
} catch (UncheckedIOException e) {
Snackbar.make(mView, R.string.text_file_write_fail, Snackbar.LENGTH_LONG).show();
}
}
notifyScriptFileChanged();
Scripts.edit(path);
} else {
Snackbar.make(mView, R.string.text_create_fail, Snackbar.LENGTH_LONG).show();
}
}
public void newScriptFile() {
newScriptFileForScript(null);
}
public Observable<String> importFile(final String pathFrom) {
try {
return importFile(PFile.getNameWithoutExtension(pathFrom), new FileInputStream(pathFrom));
} catch (FileNotFoundException e) {
showMessage(R.string.file_not_exists);
return Observable.error(e);
}
}
public Observable<String> importFile(String prefix, final InputStream inputStream) {
return showFileNameInputDialog(PFile.getNameWithoutExtension(prefix))
.observeOn(Schedulers.io())
.map(new Function<String, String>() {
@Override
public String apply(@io.reactivex.annotations.NonNull String s) throws Exception {
final String pathTo = getCurrentDirectoryPath() + s + ".js";
if (PFile.copyStream(inputStream, pathTo)) {
showMessage(R.string.text_import_succeed);
} else {
showMessage(R.string.text_import_fail);
}
notifyScriptFileChanged();
return pathTo;
}
});
}
public void newDirectory() {
showNameInputDialog("", new InputCallback(true))
.subscribe(new Consumer<String>() {
@Override
public void accept(@io.reactivex.annotations.NonNull String path) throws Exception {
if (new ScriptFile(getCurrentDirectory(), path).mkdirs()) {
showMessage(R.string.text_already_create);
notifyScriptFileChanged();
} else {
showMessage(R.string.text_create_fail);
}
}
});
}
private void notifyScriptFileChanged() {
StorageScriptProvider.getDefault().notifyDirectoryChanged(mCurrentDirectory);
}
private void showMessage(final int resId) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(mView, resId, Snackbar.LENGTH_SHORT).show();
}
});
}
private Observable<String> showFileNameInputDialog(String prefix) {
return showNameInputDialog(prefix, new InputCallback(false));
}
private Observable<String> showNameInputDialog(String prefix, MaterialDialog.InputCallback textWatcher) {
final PublishSubject<String> input = PublishSubject.create();
new ThemeColorMaterialDialogBuilder(mActivity).title(R.string.text_name)
.inputType(InputType.TYPE_CLASS_TEXT)
.alwaysCallInputCallback()
.input(getString(R.string.text_please_input_name), prefix, false, textWatcher)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
input.onNext(dialog.getInputEditText().getText().toString());
input.onComplete();
}
})
.show();
return input;
}
private CharSequence getString(int resId) {
return mActivity.getString(resId);
}
public Observable<String> importSample(Sample sample) {
try {
return importFile(sample.name, mActivity.getAssets().open(sample.path));
} catch (IOException e) {
e.printStackTrace();
Snackbar.make(mView, R.string.text_import_fail, Snackbar.LENGTH_SHORT).show();
return Observable.error(e);
}
}
public Observable<Boolean> rename(final ScriptFile file) {
String originalName = file.getSimplifiedName();
return showNameInputDialog(originalName, new InputCallback(file.isDirectory(), originalName))
.map(new Function<String, Boolean>() {
@Override
public Boolean apply(@io.reactivex.annotations.NonNull String newName) throws Exception {
return file.renameTo(newName);
}
});
}
private class InputCallback implements MaterialDialog.InputCallback {
private boolean mIsDirectory = false;
private String mExcluded;
private boolean mIsFirstTextChanged = true;
InputCallback(boolean isDirectory, String excluded) {
mIsDirectory = isDirectory;
mExcluded = excluded;
}
InputCallback(boolean isDirectory) {
mIsDirectory = isDirectory;
}
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
if (mIsFirstTextChanged) {
mIsFirstTextChanged = false;
return;
}
EditText editText = dialog.getInputEditText();
if (editText == null)
return;
int errorResId = 0;
if (input == null || input.length() == 0) {
errorResId = R.string.text_name_should_not_be_empty;
} else if (!input.equals(mExcluded)) {
if (new File(getCurrentDirectory(), mIsDirectory ? input.toString() : input.toString() + ".js").exists()) {
errorResId = R.string.text_file_exists;
}
}
if (errorResId == 0) {
editText.setError(null);
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true);
} else {
editText.setError(getString(errorResId));
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
}
}
}
}
@@ -23,6 +23,7 @@ import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.script.Scripts; import com.stardust.scriptdroid.script.Scripts;
import com.stardust.scriptdroid.script.sample.Sample; import com.stardust.scriptdroid.script.sample.Sample;
import com.stardust.scriptdroid.ui.BaseActivity; import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity; import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity;
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils; import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils;
import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity; import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity;
@@ -33,11 +34,11 @@ import com.stardust.util.SparseArrayEntries;
import com.stardust.widget.ToolbarMenuItem; import com.stardust.widget.ToolbarMenuItem;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import static com.stardust.scriptdroid.script.Scripts.ACTION_ON_EXECUTION_FINISHED; import static com.stardust.scriptdroid.script.Scripts.ACTION_ON_EXECUTION_FINISHED;
import static com.stardust.scriptdroid.script.Scripts.EXTRA_EXCEPTION_MESSAGE; import static com.stardust.scriptdroid.script.Scripts.EXTRA_EXCEPTION_MESSAGE;
@@ -118,6 +119,20 @@ public class ViewSampleActivity extends Editor920Activity implements OnActivityR
mScriptExecution = Scripts.runWithBroadcastSender(new StringScriptSource(mSample.name, mEditorDelegate.getText())); mScriptExecution = Scripts.runWithBroadcastSender(new StringScriptSource(mSample.name, mEditorDelegate.getText()));
} }
@OnClick(R.id.edit)
void edit() {
new ScriptOperations(this, mView)
.importSample(mSample)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String path) throws Exception {
EditActivity.editFile(ViewSampleActivity.this, path);
finish();
}
});
}
private void initMenuItem() { private void initMenuItem() {
mMenuMap = new SparseArrayEntries<ToolbarMenuItem>() mMenuMap = new SparseArrayEntries<ToolbarMenuItem>()
.entry(R.id.run, (ToolbarMenuItem) findViewById(R.id.run)) .entry(R.id.run, (ToolbarMenuItem) findViewById(R.id.run))
@@ -152,7 +167,9 @@ public class ViewSampleActivity extends Editor920Activity implements OnActivityR
HelpCatalogueActivity.showMainCatalogue(this); HelpCatalogueActivity.showMainCatalogue(this);
return true; return true;
case R.id.action_import: case R.id.action_import:
MainActivity.importSample(this, mSample); new ScriptOperations(this, mView)
.importSample(mSample)
.subscribe();
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@@ -40,6 +40,7 @@ import com.stardust.scriptdroid.external.open.ImportIntentActivity;
import com.stardust.scriptdroid.script.ScriptFile; import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.StorageScriptProvider; import com.stardust.scriptdroid.script.StorageScriptProvider;
import com.stardust.scriptdroid.script.sample.Sample; import com.stardust.scriptdroid.script.sample.Sample;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_; import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_;
import com.stardust.util.IntentExtras; import com.stardust.util.IntentExtras;
import com.stardust.view.accessibility.AccessibilityService; import com.stardust.view.accessibility.AccessibilityService;
@@ -67,6 +68,7 @@ import org.androidannotations.annotations.ViewById;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -221,22 +223,14 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
@Click(R.id.create_new_file) @Click(R.id.create_new_file)
void createScriptFile() { void createScriptFile() {
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() { new ScriptOperations(this, mDrawerLayout)
@Override .newScriptFile();
public void call(MyScriptListFragment myScriptListFragment) {
myScriptListFragment.newScriptFile();
}
});
} }
@Click(R.id.create_new_directory) @Click(R.id.create_new_directory)
void createNewDirectory() { void createNewDirectory() {
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() { new ScriptOperations(this, mDrawerLayout)
@Override .newDirectory();
public void call(MyScriptListFragment myScriptListFragment) {
myScriptListFragment.newDirectory();
}
});
} }
@Click(R.id.import_from_file) @Click(R.id.import_from_file)
@@ -249,12 +243,8 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
public void onFileSelection(MaterialDialog dialog, final ScriptFile file) { public void onFileSelection(MaterialDialog dialog, final ScriptFile file) {
dialog.dismiss(); dialog.dismiss();
provider.clearCacheExceptInitialDirectory(); provider.clearCacheExceptInitialDirectory();
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() { new ScriptOperations(MainActivity.this, mDrawerLayout)
@Override .importFile(file.getPath());
public void call(MyScriptListFragment myScriptListFragment) {
myScriptListFragment.importFile(file.getPath());
}
});
} }
}) })
.title(R.string.text_please_choose_file_to_import) .title(R.string.text_please_choose_file_to_import)
@@ -324,48 +314,19 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
case ACTION_IMPORT_SCRIPT: case ACTION_IMPORT_SCRIPT:
handleImportScriptFile(intent); handleImportScriptFile(intent);
break; break;
case ACTION_IMPORT_SAMPLE:
handleImportSample(intent);
break;
} }
} }
private void handleImportScriptFile(Intent intent) { private void handleImportScriptFile(Intent intent) {
mViewPager.setCurrentItem(0, true); String path = intent.getStringExtra(ARGUMENT_PATH);
MyScriptListFragment fragment = getMyScriptListFragment(); if (path != null) {
if (fragment == null) { new ScriptOperations(MainActivity.this, mDrawerLayout)
mIntentToHandle = intent; .importFile(intent.getStringExtra(ARGUMENT_PATH));
} else { return;
String path = intent.getStringExtra(ARGUMENT_PATH);
if (path != null) {
fragment.importFile(intent.getStringExtra(ARGUMENT_PATH));
return;
}
InputStream inputStream = IntentExtras.fromIntent(intent).getAndClear(ARGUMENT_INPUT_STREAM);
fragment.importFile("", inputStream);
}
}
private void handleImportSample(Intent intent) {
mViewPager.setCurrentItem(0, true);
MyScriptListFragment fragment = getMyScriptListFragment();
if (fragment == null) {
mIntentToHandle = intent;
} else {
final Sample sample = (Sample) intent.getSerializableExtra(ARGUMENT_SAMPLE);
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() {
@Override
public void call(MyScriptListFragment myScriptListFragment) {
try {
myScriptListFragment.importFile(sample.name, getAssets().open(sample.path));
} catch (IOException e) {
e.printStackTrace();
Snackbar.make(mDrawerLayout, R.string.text_import_fail, Snackbar.LENGTH_SHORT).show();
}
}
});
} }
InputStream inputStream = IntentExtras.fromIntent(intent).getAndClear(ARGUMENT_INPUT_STREAM);
new ScriptOperations(MainActivity.this, mDrawerLayout)
.importFile("", inputStream);
} }
private void handleRecordedScript(final String script) { private void handleRecordedScript(final String script) {
@@ -376,12 +337,8 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
@Override @Override
public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) { public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
if (position == 0) { if (position == 0) {
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() { new ScriptOperations(MainActivity.this, mDrawerLayout)
@Override .newScriptFileForScript(script);
public void call(MyScriptListFragment myScriptListFragment) {
myScriptListFragment.newScriptFileForScript(script);
}
});
} else { } else {
((ClipboardManager) getSystemService(CLIPBOARD_SERVICE)) ((ClipboardManager) getSystemService(CLIPBOARD_SERVICE))
.setPrimaryClip(ClipData.newPlainText("script", script)); .setPrimaryClip(ClipData.newPlainText("script", script));
@@ -418,39 +375,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
context.startActivity(intent); context.startActivity(intent);
} }
public static void importSample(Context context, Sample sample) {
context.startActivity(new Intent(context, MainActivity_.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(EXTRA_ACTION, ACTION_IMPORT_SAMPLE)
.putExtra(ARGUMENT_SAMPLE, sample));
}
public void doWithMyScriptListFragment(final Callback<MyScriptListFragment> callback) {
MyScriptListFragment fragment = ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
if (fragment != null) {
callback.call(fragment);
return;
}
mViewPager.setCurrentItem(0);
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (position == 0) {
mViewPager.removeOnPageChangeListener(this);
doWithMyScriptListFragment(callback);
}
}
});
}
@Nullable
public MyScriptListFragment getMyScriptListFragment() {
MyScriptListFragment fragment = ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
if (fragment == null) {
mViewPager.setCurrentItem(0);
}
return ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
}
@Click(R.id.toolbar) @Click(R.id.toolbar)
public void OnToolbarClick() { public void OnToolbarClick() {
@@ -12,6 +12,7 @@ import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.script.Scripts; import com.stardust.scriptdroid.script.Scripts;
import com.stardust.scriptdroid.script.sample.Sample; import com.stardust.scriptdroid.script.sample.Sample;
import com.stardust.scriptdroid.script.sample.SampleFileManager; import com.stardust.scriptdroid.script.sample.SampleFileManager;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.edit.ViewSampleActivity; import com.stardust.scriptdroid.ui.edit.ViewSampleActivity;
import com.stardust.scriptdroid.ui.main.MainActivity; import com.stardust.scriptdroid.ui.main.MainActivity;
@@ -66,7 +67,9 @@ public class SampleScriptListFragment extends Fragment {
} }
private void copySampleToMyScripts(Sample sample) { private void copySampleToMyScripts(Sample sample) {
MainActivity.importSample(getActivity(), sample); new ScriptOperations(getActivity(), getView())
.importSample(sample)
.subscribe();
} }
private void viewSample(Sample sample) { private void viewSample(Sample sample) {
@@ -22,11 +22,15 @@ import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.script.Scripts; import com.stardust.scriptdroid.script.Scripts;
import com.stardust.scriptdroid.script.StorageScriptProvider; import com.stardust.scriptdroid.script.StorageScriptProvider;
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog; import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.edit.EditActivity; import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder; import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.UnderuseExecutors; import com.stardust.util.UnderuseExecutors;
import com.stardust.widget.SimpleAdapterDataObserver; import com.stardust.widget.SimpleAdapterDataObserver;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -34,6 +38,10 @@ import java.io.InputStream;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.Optional; import butterknife.Optional;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
/** /**
* Created by Stardust on 2017/3/13. * Created by Stardust on 2017/3/13.
@@ -45,13 +53,14 @@ public class MyScriptListFragment extends Fragment {
private static final String TAG = "MyScriptListFragment"; private static final String TAG = "MyScriptListFragment";
private static ScriptFile sCurrentDirectory = StorageScriptProvider.DEFAULT_DIRECTORY;
private ScriptAndFolderListRecyclerView mScriptListRecyclerView; private ScriptAndFolderListRecyclerView mScriptListRecyclerView;
private ScriptListWithProgressBarView mScriptListWithProgressBarView; private ScriptListWithProgressBarView mScriptListWithProgressBarView;
private View mNoScriptHint; private View mNoScriptHint;
private MaterialDialog mScriptFileOperationDialog; private MaterialDialog mScriptFileOperationDialog;
private MaterialDialog mDirectoryOperationDialog; private MaterialDialog mDirectoryOperationDialog;
private ScriptFile mSelectedScriptFile; private ScriptFile mSelectedScriptFile;
private String mFilePathToImport;
@Nullable @Nullable
@Override @Override
@@ -68,10 +77,6 @@ public class MyScriptListFragment extends Fragment {
mNoScriptHint = $(R.id.hint_no_script); mNoScriptHint = $(R.id.hint_no_script);
initScriptListRecyclerView(); initScriptListRecyclerView();
initDialogs(); initDialogs();
if (mFilePathToImport != null) {
importFile(mFilePathToImport);
mFilePathToImport = null;
}
} }
private void initScriptListRecyclerView() { private void initScriptListRecyclerView() {
@@ -103,9 +108,14 @@ public class MyScriptListFragment extends Fragment {
} }
} }
}); });
mScriptListRecyclerView.setOnCurrentDirectoryChangeListener(new ScriptAndFolderListRecyclerView.OnCurrentDirectoryChangeListener() {
@Override
public void onChange(ScriptFile oldDir, ScriptFile newDir) {
sCurrentDirectory = newDir;
}
});
} }
private void initDialogs() { private void initDialogs() {
mScriptFileOperationDialog = new OperationDialogBuilder(getContext()) mScriptFileOperationDialog = new OperationDialogBuilder(getContext())
.item(R.id.loop, R.drawable.ic_loop_white_24dp, R.string.text_run_repeatedly) .item(R.id.loop, R.drawable.ic_loop_white_24dp, R.string.text_run_repeatedly)
@@ -122,107 +132,11 @@ public class MyScriptListFragment extends Fragment {
.build(); .build();
} }
public void newScriptFileForScript(final String script) {
showFileNameInputDialog("", new MaterialDialog.InputCallback() { public static ScriptFile getCurrentDirectory() {
@Override return sCurrentDirectory;
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
createScriptFile(getCurrentDirectoryPath() + input + ".js", script);
}
});
} }
private String getCurrentDirectoryPath() {
return getCurrentDirectory().getPath() + "/";
}
public void createScriptFile(String path, String script) {
if (PFile.createIfNotExists(path)) {
if (script != null) {
try {
PFile.write(path, script);
} catch (UncheckedIOException e) {
Snackbar.make(getView(), R.string.text_file_write_fail, Snackbar.LENGTH_LONG).show();
}
}
notifyScriptFileChanged();
Scripts.edit(path);
} else {
Snackbar.make(getView(), R.string.text_create_fail, Snackbar.LENGTH_LONG).show();
}
}
public void newScriptFile() {
newScriptFileForScript(null);
}
public void importFile(final String pathFrom) {
if (getActivity() == null) {
mFilePathToImport = pathFrom;
return;
}
try {
importFile(PFile.getNameWithoutExtension(pathFrom), new FileInputStream(pathFrom));
} catch (FileNotFoundException e) {
showMessage(R.string.file_not_exists);
}
}
public void importFile(String prefix, final InputStream inputStream) {
showFileNameInputDialog(PFile.getNameWithoutExtension(prefix), new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
final String pathTo = getCurrentDirectoryPath() + input + ".js";
new Thread(new Runnable() {
@Override
public void run() {
if (PFile.copyStream(inputStream, pathTo)) {
showMessage(R.string.text_import_succeed);
} else {
showMessage(R.string.text_import_fail);
}
notifyScriptFileChanged();
}
}).start();
}
});
}
public void newDirectory() {
showNameInputDialog("", new InputCallback(true), new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
if (new ScriptFile(getCurrentDirectory(), input.toString()).mkdirs()) {
showMessage(R.string.text_already_create);
notifyScriptFileChanged();
} else {
showMessage(R.string.text_create_fail);
}
}
});
}
private ScriptFile getCurrentDirectory() {
return mScriptListRecyclerView.getCurrentDirectory();
}
private void showFileNameInputDialog(String prefix, final MaterialDialog.InputCallback callback) {
showNameInputDialog(prefix, new InputCallback(false), callback);
}
private void showNameInputDialog(String prefix, MaterialDialog.InputCallback textWatcher, final MaterialDialog.InputCallback callback) {
new ThemeColorMaterialDialogBuilder(getActivity()).title(R.string.text_name)
.inputType(InputType.TYPE_CLASS_TEXT)
.alwaysCallInputCallback()
.input(getString(R.string.text_please_input_name), prefix, false, textWatcher)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
callback.onInput(dialog, dialog.getInputEditText().getText());
}
})
.show();
}
private void notifyScriptFileChanged() { private void notifyScriptFileChanged() {
getActivity().runOnUiThread(new Runnable() { getActivity().runOnUiThread(new Runnable() {
@@ -245,15 +159,15 @@ public class MyScriptListFragment extends Fragment {
@OnClick(R.id.rename) @OnClick(R.id.rename)
void renameScriptFile() { void renameScriptFile() {
dismissDialogs(); dismissDialogs();
String originalName = mSelectedScriptFile.getSimplifiedName(); new ScriptOperations(getActivity(), getView())
showNameInputDialog(originalName, new InputCallback(mSelectedScriptFile.isDirectory(), originalName), new MaterialDialog.InputCallback() { .rename(mSelectedScriptFile)
@Override .subscribe(new Consumer<Boolean>() {
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) { @Override
mSelectedScriptFile.renameTo(input.toString()); public void accept(@io.reactivex.annotations.NonNull Boolean renamed) throws Exception {
StorageScriptProvider.getDefault().notifyDirectoryChanged(mScriptListRecyclerView.getCurrentDirectory()); StorageScriptProvider.getDefault().notifyDirectoryChanged(mScriptListRecyclerView.getCurrentDirectory());
onScriptFileOperated(); onScriptFileOperated();
} }
}); });
} }
private void dismissDialogs() { private void dismissDialogs() {
@@ -274,7 +188,7 @@ public class MyScriptListFragment extends Fragment {
private void onScriptFileOperated() { private void onScriptFileOperated() {
mSelectedScriptFile = null; mSelectedScriptFile = null;
getView().post(new Runnable() { getActivity().runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
mScriptListWithProgressBarView.hideProgressBar(); mScriptListWithProgressBarView.hideProgressBar();
@@ -310,18 +224,21 @@ public class MyScriptListFragment extends Fragment {
private void doDeletingScriptFile() { private void doDeletingScriptFile() {
mScriptListWithProgressBarView.showProgressBar(); mScriptListWithProgressBarView.showProgressBar();
UnderuseExecutors.execute(new Runnable() { Observable.fromPublisher(new Publisher<Boolean>() {
@Override @Override
public void run() { public void subscribe(Subscriber<? super Boolean> s) {
if (PFile.deleteRecursively(mSelectedScriptFile)) { s.onNext(PFile.deleteRecursively(mSelectedScriptFile));
showMessage(R.string.text_already_delete);
notifyScriptFileChanged();
} else {
showMessage(R.string.text_already_delete);
}
onScriptFileOperated();
} }
}); }).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(@io.reactivex.annotations.NonNull Boolean deleted) throws Exception {
showMessage(deleted ? R.string.text_already_delete : R.string.text_delete_failed);
notifyScriptFileChanged();
onScriptFileOperated();
}
});
} }
private void showMessage(final int resId) { private void showMessage(final int resId) {
@@ -27,10 +27,19 @@ import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
/** /**
* Created by Stardust on 2017/3/27. * Created by Stardust on 2017/3/27.
*/ */
@@ -54,6 +63,12 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
void onFileListed(); void onFileListed();
} }
public interface OnCurrentDirectoryChangeListener {
void onChange(ScriptFile oldDir, ScriptFile newDir);
}
public static final int VIEW_TYPE_DIRECTORY = 1; public static final int VIEW_TYPE_DIRECTORY = 1;
public static final int VIEW_TYPE_FILE = 2; public static final int VIEW_TYPE_FILE = 2;
@@ -143,8 +158,8 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
private boolean mCanGoBack = false; private boolean mCanGoBack = false;
private StorageScriptProvider mStorageScriptProvider; private StorageScriptProvider mStorageScriptProvider;
private FileProcessListener mFileProcessListener; private FileProcessListener mFileProcessListener;
private OnCurrentDirectoryChangeListener mOnCurrentDirectoryChangeListener;
private boolean mScriptFileOperationEnabled = true; private boolean mScriptFileOperationEnabled = true;
private Executor mFileListingExecutor = Executors.newSingleThreadExecutor();
public ScriptAndFolderListRecyclerView(Context context) { public ScriptAndFolderListRecyclerView(Context context) {
super(context); super(context);
@@ -162,26 +177,31 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
} }
private void setCurrentDirectory(final ScriptFile directory, boolean canGoBack) { private void setCurrentDirectory(final ScriptFile directory, boolean canGoBack) {
if (!directory.equals(mCurrentDirectory) && mOnCurrentDirectoryChangeListener != null) {
mOnCurrentDirectoryChangeListener.onChange(mCurrentDirectory, directory);
}
mCurrentDirectory = directory; mCurrentDirectory = directory;
mCanGoBack = canGoBack; mCanGoBack = canGoBack;
if (mFileProcessListener != null) { if (mFileProcessListener != null) {
mFileProcessListener.onFilesListing(); mFileProcessListener.onFilesListing();
} }
mFileListingExecutor.execute(new Runnable() { Observable.fromPublisher(new Publisher<ScriptFile[]>() {
@Override @Override
public void run() { public void subscribe(Subscriber<? super ScriptFile[]> s) {
final ScriptFile[] scriptFiles = mStorageScriptProvider.getDirectoryScriptFiles(directory); s.onNext(mStorageScriptProvider.getDirectoryScriptFiles(directory));
post(new Runnable() { s.onComplete();
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ScriptFile[]>() {
@Override @Override
public void run() { public void accept(@NonNull ScriptFile[] scriptFiles) throws Exception {
mAdapter.setScripts(scriptFiles); mAdapter.setScripts(scriptFiles);
if (mFileProcessListener != null) if (mFileProcessListener != null)
mFileProcessListener.onFileListed(); mFileProcessListener.onFileListed();
smoothScrollToPosition(0); smoothScrollToPosition(0);
} }
}); });
}
});
} }
public void setCurrentDirectory(final ScriptFile directory) { public void setCurrentDirectory(final ScriptFile directory) {
@@ -216,6 +236,10 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
mOnItemLongClickListener = onItemLongClickListener; mOnItemLongClickListener = onItemLongClickListener;
} }
public void setOnCurrentDirectoryChangeListener(OnCurrentDirectoryChangeListener onCurrentDirectoryChangeListener) {
mOnCurrentDirectoryChangeListener = onCurrentDirectoryChangeListener;
}
public ScriptFile getCurrentDirectory() { public ScriptFile getCurrentDirectory() {
return mCurrentDirectory; return mCurrentDirectory;
} }
@@ -297,7 +321,7 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
return false; return false;
} }
@Subscribe @Subscribe(threadMode = ThreadMode.MAIN)
public void onDirectoryChange(StorageScriptProvider.DirectoryChangeEvent event) { public void onDirectoryChange(StorageScriptProvider.DirectoryChangeEvent event) {
if (event.directory.equals(mCurrentDirectory)) { if (event.directory.equals(mCurrentDirectory)) {
updateCurrentDirectory(); updateCurrentDirectory();
@@ -45,6 +45,8 @@ public class TaskManagerFragment extends Fragment {
mTaskListRecyclerView.postDelayed(new Runnable() { mTaskListRecyclerView.postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mNoRunningScriptNotice == null)
return;
mNoRunningScriptNotice.setVisibility(noRunningScript ? View.VISIBLE : View.GONE); mNoRunningScriptNotice.setVisibility(noRunningScript ? View.VISIBLE : View.GONE);
mCloseAllView.setVisibility(noRunningScript ? View.GONE : View.VISIBLE); mCloseAllView.setVisibility(noRunningScript ? View.GONE : View.VISIBLE);
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

@@ -27,6 +27,14 @@
android:layout_gravity="right" android:layout_gravity="right"
android:orientation="horizontal"> android:orientation="horizontal">
<com.stardust.widget.ToolbarMenuItem
android:id="@+id/edit"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_edit_white_24dp"
app:icon_color="@android:color/white"
app:text="@string/text_edit"/>
<com.stardust.widget.ToolbarMenuItem <com.stardust.widget.ToolbarMenuItem
android:id="@+id/run" android:id="@+id/run"
android:layout_width="40dp" android:layout_width="40dp"
@@ -35,6 +43,8 @@
app:icon_color="@android:color/white" app:icon_color="@android:color/white"
app:text="@string/text_run"/> app:text="@string/text_run"/>
</LinearLayout> </LinearLayout>
</com.stardust.theme.widget.ThemeColorToolbar> </com.stardust.theme.widget.ThemeColorToolbar>
+1
View File
@@ -211,6 +211,7 @@
<string name="script_anr">没有相应,要强制停止吗</string> <string name="script_anr">没有相应,要强制停止吗</string>
<string name="text_enable_accessibitliy_service_by_root_failed">使用root权限开启失败</string> <string name="text_enable_accessibitliy_service_by_root_failed">使用root权限开启失败</string>
<string name="text_on_progress">处理中</string> <string name="text_on_progress">处理中</string>
<string name="text_delete_failed">删除失败</string>
<string-array name="record_control_keys"> <string-array name="record_control_keys">
@@ -142,7 +142,7 @@ public class PFile {
return false; return false;
FileOutputStream fos = new FileOutputStream(file); FileOutputStream fos = new FileOutputStream(file);
write(is, fos); write(is, fos);
return false; return true;
} catch (IOException | UncheckedIOException e) { } catch (IOException | UncheckedIOException e) {
e.printStackTrace(); e.printStackTrace();
return false; return false;