Skip to content

Commit

Permalink
[WIP] Add context menu "Open in Terminal" option
Browse files Browse the repository at this point in the history
  • Loading branch information
TranceLove committed Jul 3, 2024
1 parent bdc86af commit e968660
Show file tree
Hide file tree
Showing 21 changed files with 904 additions and 27 deletions.
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="com.termux.permission.RUN_COMMAND" />
<uses-permission android:name="com.termoneplus.permission.RUN_SCRIPT" />
<uses-permission android:name="jackpal.androidterm.permission.RUN_SCRIPT" />

<uses-feature
android:name="android.hardware.touchscreen"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ class AppsRecyclerAdapter(
MaterialDialog.Builder(fragment.requireContext())
builder1
.theme(
themedActivity.appTheme.getMaterialDialogTheme(),
themedActivity.appTheme.materialDialogTheme,
)
.content(fragment.getString(R.string.unin_system_apk))
.title(fragment.getString(R.string.warning))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1435,13 +1435,15 @@ private void showPopup(@NonNull View view, @NonNull final LayoutElementParcelabl
if (rowItem.isDirectory) {
popupMenu.getMenu().findItem(R.id.open_with).setVisible(false);
popupMenu.getMenu().findItem(R.id.share).setVisible(false);
popupMenu.getMenu().findItem(R.id.open_in_terminal).setVisible(true);

if (mainFragment.getMainActivity().mReturnIntent) {
popupMenu.getMenu().findItem(R.id.return_select).setVisible(true);
}
} else {
popupMenu.getMenu().findItem(R.id.book).setVisible(false);
popupMenu.getMenu().findItem(R.id.compress).setVisible(true);
popupMenu.getMenu().findItem(R.id.open_in_terminal).setVisible(false);

if (description.endsWith(fileExtensionZip)
|| description.endsWith(fileExtensionJar)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,11 @@ public static void installApk(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& !permissionsActivity.getPackageManager().canRequestPackageInstalls()) {
permissionsActivity.requestInstallApkPermission(
() -> installApk(f, permissionsActivity), true);
(input) -> {
installApk(f, permissionsActivity);
return null;
},
true);
}

Intent intent = new Intent(Intent.ACTION_VIEW);
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/amaze/filemanager/ui/ItemPopupMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.amaze.filemanager.ui.dialogs.EncryptAuthenticateDialog;
import com.amaze.filemanager.ui.dialogs.EncryptWithPresetPasswordSaveAsDialog;
import com.amaze.filemanager.ui.dialogs.GeneralDialogCreation;
import com.amaze.filemanager.ui.dialogs.OpenFolderInTerminalFragment;
import com.amaze.filemanager.ui.fragments.MainFragment;
import com.amaze.filemanager.ui.fragments.preferencefragments.PreferencesConstants;
import com.amaze.filemanager.ui.provider.UtilitiesProvider;
Expand Down Expand Up @@ -256,6 +257,9 @@ public void onButtonPressed(Intent intent, String password)
case R.id.return_select:
mainFragment.returnIntentResults(new HybridFileParcelable[] {rowItem.generateBaseFile()});
return true;
case R.id.open_in_terminal:
OpenFolderInTerminalFragment.Companion.openTerminalOrShow(rowItem.desc, mainActivity);
return true;
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public class MainActivity extends PermissionsActivity
CloudConnectionCallbacks,
LoaderManager.LoaderCallbacks<Cursor>,
FolderChooserDialog.FolderCallback,
PermissionsActivity.OnPermissionGranted {
Function<Void, Void> {

private static final Logger LOG = LoggerFactory.getLogger(MainActivity.class);

Expand Down Expand Up @@ -532,7 +532,7 @@ public void invalidateFragmentAndBundle(Bundle savedInstanceState, boolean isClo

@Override
@SuppressLint("CheckResult")
public void onPermissionGranted() {
public Void apply(Void input) {
drawer.refreshDrawer();
TabFragment tabFragment = getTabFragment();
boolean b = getBoolean(PREFERENCE_NEED_TO_SET_HOME);
Expand Down Expand Up @@ -561,6 +561,7 @@ public void onPermissionGranted() {
if (main1 != null) ((MainFragment) main1).updateList(false);
}
}
return null;
}

private void checkForExternalPermission() {
Expand Down Expand Up @@ -1120,6 +1121,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.hiddenitems).setVisible(true);
menu.findItem(R.id.view).setVisible(true);
menu.findItem(R.id.extract).setVisible(false);
menu.findItem(R.id.open_in_terminal).setVisible(true);
invalidatePasteSnackbar(true);
findViewById(R.id.buttonbarframe).setVisibility(View.VISIBLE);
} else if (fragment instanceof AppsListFragment
Expand All @@ -1133,6 +1135,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.home).setVisible(false);
menu.findItem(R.id.history).setVisible(false);
menu.findItem(R.id.extract).setVisible(false);
menu.findItem(R.id.open_in_terminal).setVisible(false);
if (fragment instanceof ProcessViewerFragment) {
menu.findItem(R.id.sort).setVisible(false);
} else if (fragment instanceof FtpServerFragment) {
Expand All @@ -1156,6 +1159,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.hiddenitems).setVisible(false);
menu.findItem(R.id.view).setVisible(false);
menu.findItem(R.id.extract).setVisible(true);
menu.findItem(R.id.open_in_terminal).setVisible(false);
invalidatePasteSnackbar(false);
}
return super.onPrepareOptionsMenu(menu);
Expand Down Expand Up @@ -1291,6 +1295,10 @@ public boolean onOptionsItemSelected(MenuItem item) {
break;
case R.id.search:
getAppbar().getSearchView().revealSearchView();
break;
case R.id.open_in_terminal:
if (getFragmentAtFrame() instanceof MainFragment) {}

break;
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,22 @@

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.arch.core.util.Function;
import androidx.core.app.ActivityCompat;

public class PermissionsActivity extends ThemedActivity
implements ActivityCompat.OnRequestPermissionsResultCallback {

private static final String TAG = PermissionsActivity.class.getSimpleName();

public static final int PERMISSION_LENGTH = 4;
public static final int PERMISSION_LENGTH = 5;
public static final int STORAGE_PERMISSION = 0,
INSTALL_APK_PERMISSION = 1,
ALL_FILES_PERMISSION = 2,
NOTIFICATION_PERMISSION = 3;
NOTIFICATION_PERMISSION = 3,
TERMINAL_PERMISSION = 4;

private final OnPermissionGranted[] permissionCallbacks =
new OnPermissionGranted[PERMISSION_LENGTH];
private final Function<Void, Void>[] permissionCallbacks = new Function[PERMISSION_LENGTH];

@Override
public void onRequestPermissionsResult(
Expand All @@ -68,7 +69,7 @@ public void onRequestPermissionsResult(
if (requestCode == STORAGE_PERMISSION) {
if (isGranted(grantResults)) {
Utils.enableScreenRotation(this);
permissionCallbacks[STORAGE_PERMISSION].onPermissionGranted();
permissionCallbacks[STORAGE_PERMISSION].apply(null);
permissionCallbacks[STORAGE_PERMISSION] = null;
} else {
Toast.makeText(this, R.string.grantfailed, Toast.LENGTH_SHORT).show();
Expand All @@ -83,7 +84,7 @@ public void onRequestPermissionsResult(
}
} else if (requestCode == INSTALL_APK_PERMISSION) {
if (isGranted(grantResults)) {
permissionCallbacks[INSTALL_APK_PERMISSION].onPermissionGranted();
permissionCallbacks[INSTALL_APK_PERMISSION].apply(null);
permissionCallbacks[INSTALL_APK_PERMISSION] = null;
}
}
Expand Down Expand Up @@ -128,14 +129,12 @@ public void requestNotificationPermission(boolean isInitialStart) {
Manifest.permission.POST_NOTIFICATIONS,
NOTIFICATION_PERMISSION,
materialDialog,
() -> {
// do nothing
},
input -> null,
isInitialStart);
}

public void requestStoragePermission(
@NonNull final OnPermissionGranted onPermissionGranted, boolean isInitialStart) {
@NonNull final Function<Void, Void> onPermissionGranted, boolean isInitialStart) {
Utils.disableScreenRotation(this);
final MaterialDialog materialDialog =
GeneralDialogCreation.showBasicDialog(
Expand All @@ -157,7 +156,7 @@ public void requestStoragePermission(

@RequiresApi(api = Build.VERSION_CODES.M)
public void requestInstallApkPermission(
@NonNull final OnPermissionGranted onPermissionGranted, boolean isInitialStart) {
@NonNull final Function<Void, Void> onPermissionGranted, boolean isInitialStart) {
final MaterialDialog materialDialog =
GeneralDialogCreation.showBasicDialog(
this,
Expand All @@ -178,6 +177,24 @@ public void requestInstallApkPermission(
isInitialStart);
}

public void requestTerminalPermission(
final String permission, @NonNull final Function<Void, Void> onPermissionGranted) {

final MaterialDialog materialDialog =
GeneralDialogCreation.showBasicDialog(
this,
R.string.grant_apkinstall_permission,
R.string.grantper,
R.string.grant,
R.string.cancel);
materialDialog
.getActionButton(DialogAction.NEGATIVE)
.setOnClickListener(v -> materialDialog.dismiss());
materialDialog.setCancelable(false);

requestPermission(permission, TERMINAL_PERMISSION, materialDialog, onPermissionGranted, false);
}

/**
* Requests permission, overrides {@param rationale}'s POSITIVE button dialog action.
*
Expand All @@ -193,7 +210,7 @@ private void requestPermission(
final String permission,
final int code,
@NonNull final MaterialDialog rationale,
@NonNull final OnPermissionGranted onPermissionGranted,
@NonNull final Function<Void, Void> onPermissionGranted,
boolean isInitialStart) {
permissionCallbacks[code] = onPermissionGranted;

Expand Down Expand Up @@ -239,7 +256,7 @@ private void requestPermission(
*
* @param onPermissionGranted permission granted callback
*/
public void requestAllFilesAccess(@NonNull final OnPermissionGranted onPermissionGranted) {
public void requestAllFilesAccess(@NonNull final Function<Void, Void> onPermissionGranted) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
final MaterialDialog materialDialog =
GeneralDialogCreation.showBasicDialog(
Expand All @@ -263,7 +280,7 @@ public void requestAllFilesAccess(@NonNull final OnPermissionGranted onPermissio

@RequiresApi(api = Build.VERSION_CODES.R)
private void requestAllFilesAccessPermission(
@NonNull final OnPermissionGranted onPermissionGranted) {
@NonNull final Function<Void, Void> onPermissionGranted) {
Utils.disableScreenRotation(this);
permissionCallbacks[ALL_FILES_PERMISSION] = onPermissionGranted;
try {
Expand All @@ -290,8 +307,4 @@ private void requestAllFilesAccessPermission(
private boolean isGranted(int[] grantResults) {
return grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
}

public interface OnPermissionGranted {
void onPermissionGranted();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.amaze.filemanager.ui.dialogs

import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.amaze.filemanager.R
import com.amaze.filemanager.adapters.AppsRecyclerAdapter
import com.amaze.filemanager.adapters.data.AppDataParcelable
import com.amaze.filemanager.adapters.glide.AppsAdapterPreloadModel
import com.amaze.filemanager.adapters.holders.AppHolder
import com.amaze.filemanager.databinding.FragmentOpenFileDialogBinding
import com.amaze.filemanager.ui.activities.MainActivity
import com.amaze.filemanager.ui.base.BaseBottomSheetFragment
import com.amaze.filemanager.ui.fragments.AdjustListViewForTv
import com.amaze.filemanager.utils.GlideConstants
import com.bumptech.glide.Glide
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
import com.bumptech.glide.util.ViewPreloadSizeProvider

abstract class AbstractChooseAppToOpenFragment :
BaseBottomSheetFragment(),
AdjustListViewForTv<AppHolder> {
protected var fragmentOpenFileDialogBinding: FragmentOpenFileDialogBinding? = null
protected val viewBinding get() = fragmentOpenFileDialogBinding!!

private lateinit var adapter: AppsRecyclerAdapter
private lateinit var sharedPreferences: SharedPreferences

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.appBottomSheetDialogTheme)
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
fragmentOpenFileDialogBinding = FragmentOpenFileDialogBinding.inflate(inflater)
initDialogResources(viewBinding.parent)
return viewBinding.root
}

override fun onViewCreated(
view: View,
savedInstanceState: Bundle?,
) {
super.onViewCreated(view, savedInstanceState)

val modelProvider = AppsAdapterPreloadModel(this, true)
val sizeProvider = ViewPreloadSizeProvider<String>()
val preloader =
RecyclerViewPreloader(
Glide.with(this),
modelProvider,
sizeProvider,
GlideConstants.MAX_PRELOAD_FILES,
)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())

val appDataParcelableList = loadAppList()

adapter =
AppsRecyclerAdapter(
this,
modelProvider,
true,
this,
appDataParcelableList,
)
loadViews()
viewBinding.appsRecyclerView.addOnScrollListener(preloader)
}

override fun onDestroyView() {
super.onDestroyView()
fragmentOpenFileDialogBinding = null
}

override fun onPause() {
super.onPause()
dismiss()
}

private fun loadViews() {
viewBinding.run {
appsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
appsRecyclerView.adapter = adapter
doLoadViewsWith(this)
}
}

protected open fun doLoadViewsWith(viewBinding: FragmentOpenFileDialogBinding) = Unit

protected abstract fun loadAppList(): MutableList<AppDataParcelable>

protected abstract fun initLastAppData(
lastClassAndPackage: List<String>?,
appDataParcelableList: MutableList<AppDataParcelable>,
): AppDataParcelable?

override fun adjustListViewForTv(
viewHolder: AppHolder,
mainActivity: MainActivity,
) {
// do nothing
}
}
Loading

0 comments on commit e968660

Please sign in to comment.