diff --git a/app/src/main/java/com/itsaky/androidide/EditorActivity.java b/app/src/main/java/com/itsaky/androidide/EditorActivity.java index 52cf2ca85..7e70aa60b 100644 --- a/app/src/main/java/com/itsaky/androidide/EditorActivity.java +++ b/app/src/main/java/com/itsaky/androidide/EditorActivity.java @@ -17,7 +17,11 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.LinearLayout; import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.view.menu.MenuBuilder; import androidx.core.content.ContextCompat; import androidx.core.view.GravityCompat; import androidx.fragment.app.Fragment; @@ -48,6 +52,7 @@ import com.itsaky.androidide.app.StudioActivity; import com.itsaky.androidide.databinding.ActivityEditorBinding; import com.itsaky.androidide.databinding.LayoutCreateFileJavaBinding; import com.itsaky.androidide.databinding.LayoutDialogTextInputBinding; +import com.itsaky.androidide.databinding.LayoutSearchProjectBinding; import com.itsaky.androidide.fragments.EditorFragment; import com.itsaky.androidide.fragments.FileTreeFragment; import com.itsaky.androidide.fragments.sheets.OptionsListFragment; @@ -72,6 +77,7 @@ import com.itsaky.androidide.utils.Environment; import com.itsaky.androidide.utils.Logger; import com.itsaky.androidide.utils.PreferenceManager; import com.itsaky.androidide.utils.ProjectWriter; +import com.itsaky.androidide.utils.RecursiveFileSearcher; import com.itsaky.androidide.utils.Symbols; import com.itsaky.androidide.utils.TypefaceUtils; import com.itsaky.androidide.utils.VersionedFileManager; @@ -115,11 +121,6 @@ import java.util.Stack; import java.util.regex.Pattern; import me.piruin.quickaction.ActionItem; import me.piruin.quickaction.QuickAction; -import androidx.appcompat.app.AlertDialog; -import com.itsaky.androidide.databinding.LayoutSearchProjectBinding; -import android.widget.CheckBox; -import android.widget.LinearLayout; -import com.itsaky.androidide.utils.RecursiveFileSearcher; public class EditorActivity extends StudioActivity implements FileTreeFragment.FileActionListener, IDEService.BuildListener, @@ -258,7 +259,7 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F GradientDrawable gd = new GradientDrawable(); gd.setShape(GradientDrawable.RECTANGLE); gd.setColor(0xff212121); - gd.setStroke(2, 0xffffffff); + gd.setStroke(1, 0xffffffff); gd.setCornerRadius(8); mBinding.symbolText.setBackgroundDrawable(gd); mBinding.symbolText.setVisibility(View.GONE); @@ -445,8 +446,13 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F return true; } + @SuppressLint("RestrictedApi") @Override public boolean onCreateOptionsMenu(Menu menu) { + if(menu instanceof MenuBuilder){ + MenuBuilder builder = (MenuBuilder) menu; + builder.setOptionalIconsVisible(true); + } getMenuInflater().inflate(R.menu.menu_editor, menu); return true; } @@ -532,6 +538,7 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.AppTheme_MaterialAlertDialog); builder.setTitle(R.string.menu_find_project); builder.setView(binding.getRoot()); + builder.setCancelable(false); builder.setPositiveButton(R.string.menu_find, (dialog, which) -> { final String text = binding.input.getEditText().getText().toString().trim(); if(text == null || text.isEmpty()) { @@ -1838,6 +1845,11 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F p.textDocument = id; didClose(p); + if(mPagerAdapter.getCount() <= 0) { + mCurrentFragment = null; + mCurrentFile = null; + } + invalidateOptionsMenu(); } } diff --git a/app/src/main/java/com/itsaky/androidide/app/StudioApp.java b/app/src/main/java/com/itsaky/androidide/app/StudioApp.java index 14d589eed..f0b7cdc67 100644 --- a/app/src/main/java/com/itsaky/androidide/app/StudioApp.java +++ b/app/src/main/java/com/itsaky/androidide/app/StudioApp.java @@ -90,7 +90,7 @@ public class StudioApp extends MultiDexApplication extractLogsenderIfNeeded(); extractCleanerIfNeeded(); - newShell(line -> handleLog(line)).bgAppend("androidide-cleaner && logcat -v threadtime"); +// newShell(line -> handleLog(line)).bgAppend("androidide-cleaner && logcat -v threadtime"); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannels(); diff --git a/app/src/main/java/com/itsaky/androidide/shell/ShellServer.java b/app/src/main/java/com/itsaky/androidide/shell/ShellServer.java index 06e4b4951..ffff98528 100644 --- a/app/src/main/java/com/itsaky/androidide/shell/ShellServer.java +++ b/app/src/main/java/com/itsaky/androidide/shell/ShellServer.java @@ -58,7 +58,7 @@ public class ShellServer extends Thread { append(stringBuilder.toString(), false); // Make sure there are proper permissions set to the $HOME directory - append("chmod -R 777 $HOME"); + append("chmod -R 777 $HOME", false); } catch (Throwable th) { if (callback != null) { String out = ThrowableUtils.getFullStackTrace(th).concat("\n"); diff --git a/app/src/main/java/io/github/rosemoe/editor/widget/CodeEditor.java b/app/src/main/java/io/github/rosemoe/editor/widget/CodeEditor.java index 918987c69..f72f736f8 100644 --- a/app/src/main/java/io/github/rosemoe/editor/widget/CodeEditor.java +++ b/app/src/main/java/io/github/rosemoe/editor/widget/CodeEditor.java @@ -16,7 +16,6 @@ package io.github.rosemoe.editor.widget; import android.annotation.SuppressLint; -import android.app.AlertDialog; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -35,9 +34,9 @@ import android.text.InputType; import android.util.AttributeSet; import android.util.MutableInt; import android.util.TypedValue; -import android.view.ActionMode; import android.view.GestureDetector; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; @@ -50,16 +49,22 @@ import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; import android.widget.OverScroller; import android.widget.SearchView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Px; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.view.ActionMode; +import androidx.appcompat.view.menu.MenuBuilder; +import com.blankj.utilcode.util.ThrowableUtils; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.itsaky.androidide.R; +import com.itsaky.androidide.databinding.LayoutDialogTextInputBinding; import com.itsaky.androidide.interfaces.JLSRequestor; import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE; +import com.itsaky.androidide.utils.Logger; import com.itsaky.androidide.utils.TypefaceUtils; import com.itsaky.androidide.utils.VersionedFileManager; import com.itsaky.lsp.Diagnostic; @@ -67,7 +72,11 @@ import com.itsaky.lsp.DiagnosticSeverity; import com.itsaky.lsp.DidChangeTextDocumentParams; import com.itsaky.lsp.Position; import com.itsaky.lsp.Range; +import com.itsaky.lsp.ReferenceContext; +import com.itsaky.lsp.ReferenceParams; import com.itsaky.lsp.TextDocumentContentChangeEvent; +import com.itsaky.lsp.TextDocumentIdentifier; +import com.itsaky.lsp.TextDocumentPositionParams; import com.itsaky.lsp.VersionedTextDocumentIdentifier; import io.github.rosemoe.editor.interfaces.EditorEventListener; import io.github.rosemoe.editor.interfaces.EditorLanguage; @@ -96,15 +105,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import com.itsaky.androidide.utils.Logger; -import com.blankj.utilcode.util.ThrowableUtils; -import com.itsaky.lsp.TextDocumentPositionParams; -import com.itsaky.lsp.TextDocumentIdentifier; -import com.itsaky.lsp.ReferenceParams; -import com.itsaky.lsp.ReferenceContext; -import com.itsaky.androidide.databinding.LayoutDialogTextInputBinding; -import android.view.LayoutInflater; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; /** * CodeEditor is a editor that can highlight text regions by doing basic syntax analyzing @@ -2966,17 +2966,22 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca */ public void beginSearchMode() { class SearchActionMode implements ActionMode.Callback { - + + @SuppressLint("RestrictedApi") @Override - public boolean onCreateActionMode(ActionMode p1, Menu p2) { + public boolean onCreateActionMode(ActionMode mode, Menu menu) { mStartedActionMode = ACTION_MODE_SEARCH_TEXT; - p2.add(0, 1, 0, R.string.last) + if(menu instanceof MenuBuilder){ + MenuBuilder builder = (MenuBuilder) menu; + builder.setOptionalIconsVisible(true); + } + menu.add(0, 1, 0, R.string.last) .setIcon(R.drawable.ic_search_last) .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); - p2.add(0, 0, 0, R.string.next) + menu.add(0, 0, 0, R.string.next) .setIcon(R.drawable.ic_search_next) .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); - p2.add(0, 2, 0, R.string.replace) + menu.add(0, 2, 0, R.string.replace) .setIcon(R.drawable.ic_search_replace) .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); SearchView sv = new SearchView(getContext()); @@ -2995,7 +3000,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca } }); - p1.setCustomView(sv); + mode.setCustomView(sv); sv.performClick(); sv.setQueryHint(getContext().getString(R.string.text_to_search)); sv.setIconifiedByDefault(false); @@ -3050,7 +3055,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca } ActionMode.Callback callback = new SearchActionMode(); - startActionMode(callback); + ((AppCompatActivity) getContext()).startSupportActionMode(callback); } public EditorTouchEventHandler getEventHandler() { diff --git a/app/src/main/java/io/github/rosemoe/editor/widget/EditorTextActionModeStarter.java b/app/src/main/java/io/github/rosemoe/editor/widget/EditorTextActionModeStarter.java index 3f7ef610b..ad2937d49 100644 --- a/app/src/main/java/io/github/rosemoe/editor/widget/EditorTextActionModeStarter.java +++ b/app/src/main/java/io/github/rosemoe/editor/widget/EditorTextActionModeStarter.java @@ -15,12 +15,14 @@ */ package io.github.rosemoe.editor.widget; +import android.annotation.SuppressLint; import android.content.res.TypedArray; -import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; - +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.view.ActionMode; +import androidx.appcompat.view.menu.MenuBuilder; import io.github.rosemoe.editor.util.IntPair; /** @@ -36,16 +38,21 @@ class EditorTextActionModeStarter implements CodeEditor.EditorTextActionPresente EditorTextActionModeStarter(CodeEditor editor) { mEditor = editor; } - + + @SuppressLint("RestrictedApi") @Override public void onBeginTextSelect() { if (mActionMode != null) { return; } - mActionMode = mEditor.startActionMode(new ActionMode.Callback() { + mActionMode = ((AppCompatActivity) mEditor.getContext()).startSupportActionMode(new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { mEditor.mStartedActionMode = CodeEditor.ACTION_MODE_SELECT_TEXT; + if(menu instanceof MenuBuilder){ + MenuBuilder builder = (MenuBuilder) menu; + builder.setOptionalIconsVisible(true); + } actionMode.setTitle(android.R.string.selectTextMode); TypedArray array = mEditor.getContext().getTheme().obtainStyledAttributes(new int[]{ android.R.attr.actionModeSelectAllDrawable, @@ -55,36 +62,55 @@ class EditorTextActionModeStarter implements CodeEditor.EditorTextActionPresente }); menu.add(0, 0, 0, mEditor.getContext().getString(android.R.string.selectAll)) - .setShowAsActionFlags(2) - .setIcon(array.getDrawable(0)); + .setShowAsActionFlags(2) + .setIcon(array.getDrawable(0)); menu.add(0, 1, 0, mEditor.getContext().getString(android.R.string.cut)) - .setShowAsActionFlags(2) - .setIcon(array.getDrawable(1)); + .setShowAsActionFlags(2) + .setIcon(array.getDrawable(1)); menu.add(0, 2, 0, mEditor.getContext().getString(android.R.string.copy)) - .setShowAsActionFlags(2) - .setIcon(array.getDrawable(2)); - + .setShowAsActionFlags(2) + .setIcon(array.getDrawable(2)); + menu.add(0, 3, 0, mEditor.getContext().getString(android.R.string.paste)) - .setShowAsActionFlags(2) - .setIcon(array.getDrawable(3)); + .setShowAsActionFlags(2) + .setIcon(array.getDrawable(3)); menu.add(0, 4, 0, mEditor.getContext().getString(com.itsaky.androidide.R.string.menu_navigate_definition)) .setIcon(com.itsaky.androidide.R.drawable.ic_goto_definition); + menu.add(0, 5, 0, mEditor.getContext().getString(com.itsaky.androidide.R.string.menu_navigate_references)) .setIcon(com.itsaky.androidide.R.drawable.ic_find_references); + menu.add(0, 6, 0, mEditor.getContext().getString(com.itsaky.androidide.R.string.menu_comment_line)) .setIcon(com.itsaky.androidide.R.drawable.ic_comment_line); + menu.add(0, 7, 0, mEditor.getContext().getString(com.itsaky.androidide.R.string.menu_uncomment_line)) .setIcon(com.itsaky.androidide.R.drawable.ic_uncomment_line); + array.recycle(); return true; } @Override public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { - return false; + if(mEditor.getFile() == null) return false; + + final String name = mEditor.getFile().getName(); + final boolean isJava = name.endsWith(".java") || name.endsWith(".gradle"); + final boolean isXml = name.endsWith(".xml"); + final MenuItem def = menu.findItem(4); + final MenuItem ref = menu.findItem(5); + final MenuItem comment = menu.findItem(6); + final MenuItem uncomment = menu.findItem(7); + + def.setEnabled(isJava).getIcon().setAlpha(isJava ? 255 : 76); + ref.setEnabled(isJava).getIcon().setAlpha(isJava ? 255 : 76); + comment.setEnabled(isJava || isXml).getIcon().setAlpha(isJava || isXml ? 255 : 76); + uncomment.setEnabled(isJava || isXml).getIcon().setAlpha(isJava || isXml ? 255 : 76); + + return true; } @Override diff --git a/app/src/main/res/drawable/ic_code.xml b/app/src/main/res/drawable/ic_code.xml new file mode 100644 index 000000000..ec4671f7f --- /dev/null +++ b/app/src/main/res/drawable/ic_code.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/menu/menu_editor.xml b/app/src/main/res/menu/menu_editor.xml index 80079da49..1500d93fe 100644 --- a/app/src/main/res/menu/menu_editor.xml +++ b/app/src/main/res/menu/menu_editor.xml @@ -106,7 +106,7 @@ android:title="@string/save" app:showAsAction="ifRoom"/> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2d368357c..d223a15b1 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,19 +1,24 @@ +