Skip to content

Commit 8d5ea9a

Browse files
committed
[WIP] Add context menu "Open in Terminal" option
Fixes TeamAmaze#2666
1 parent bdc86af commit 8d5ea9a

18 files changed

+783
-5
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@
4040
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
4141
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
4242
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
43+
<uses-permission android:name="com.termux.permission.RUN_COMMAND" />
44+
<uses-permission android:name="com.termoneplus.permission.RUN_SCRIPT" />
45+
46+
<uses-permission android:name="jackpal.androidterm.permission.RUN_SCRIPT" />
47+
<uses-permission android:name="com.termoneplus.permission.RUN_SCRIPT" />
48+
<uses-permission android:name="yarolegovich.materialterminal.permission.RUN_SCRIPT" />
4349

4450
<uses-feature
4551
android:name="android.hardware.touchscreen"

app/src/main/java/com/amaze/filemanager/adapters/AppsRecyclerAdapter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ class AppsRecyclerAdapter(
508508
MaterialDialog.Builder(fragment.requireContext())
509509
builder1
510510
.theme(
511-
themedActivity.appTheme.getMaterialDialogTheme(),
511+
themedActivity.appTheme.materialDialogTheme,
512512
)
513513
.content(fragment.getString(R.string.unin_system_apk))
514514
.title(fragment.getString(R.string.warning))

app/src/main/java/com/amaze/filemanager/adapters/RecyclerAdapter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,13 +1435,15 @@ private void showPopup(@NonNull View view, @NonNull final LayoutElementParcelabl
14351435
if (rowItem.isDirectory) {
14361436
popupMenu.getMenu().findItem(R.id.open_with).setVisible(false);
14371437
popupMenu.getMenu().findItem(R.id.share).setVisible(false);
1438+
popupMenu.getMenu().findItem(R.id.open_in_terminal).setVisible(true);
14381439

14391440
if (mainFragment.getMainActivity().mReturnIntent) {
14401441
popupMenu.getMenu().findItem(R.id.return_select).setVisible(true);
14411442
}
14421443
} else {
14431444
popupMenu.getMenu().findItem(R.id.book).setVisible(false);
14441445
popupMenu.getMenu().findItem(R.id.compress).setVisible(true);
1446+
popupMenu.getMenu().findItem(R.id.open_in_terminal).setVisible(false);
14451447

14461448
if (description.endsWith(fileExtensionZip)
14471449
|| description.endsWith(fileExtensionJar)

app/src/main/java/com/amaze/filemanager/ui/ItemPopupMenu.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.amaze.filemanager.ui.dialogs.EncryptAuthenticateDialog;
3838
import com.amaze.filemanager.ui.dialogs.EncryptWithPresetPasswordSaveAsDialog;
3939
import com.amaze.filemanager.ui.dialogs.GeneralDialogCreation;
40+
import com.amaze.filemanager.ui.dialogs.OpenFolderInTerminalFragment;
4041
import com.amaze.filemanager.ui.fragments.MainFragment;
4142
import com.amaze.filemanager.ui.fragments.preferencefragments.PreferencesConstants;
4243
import com.amaze.filemanager.ui.provider.UtilitiesProvider;
@@ -256,6 +257,9 @@ public void onButtonPressed(Intent intent, String password)
256257
case R.id.return_select:
257258
mainFragment.returnIntentResults(new HybridFileParcelable[] {rowItem.generateBaseFile()});
258259
return true;
260+
case R.id.open_in_terminal:
261+
OpenFolderInTerminalFragment.Companion.openTerminalOrShow(rowItem.desc, mainActivity);
262+
return true;
259263
}
260264
return false;
261265
}

app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
11201120
menu.findItem(R.id.hiddenitems).setVisible(true);
11211121
menu.findItem(R.id.view).setVisible(true);
11221122
menu.findItem(R.id.extract).setVisible(false);
1123+
menu.findItem(R.id.open_in_terminal).setVisible(true);
11231124
invalidatePasteSnackbar(true);
11241125
findViewById(R.id.buttonbarframe).setVisibility(View.VISIBLE);
11251126
} else if (fragment instanceof AppsListFragment
@@ -1133,6 +1134,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
11331134
menu.findItem(R.id.home).setVisible(false);
11341135
menu.findItem(R.id.history).setVisible(false);
11351136
menu.findItem(R.id.extract).setVisible(false);
1137+
menu.findItem(R.id.open_in_terminal).setVisible(false);
11361138
if (fragment instanceof ProcessViewerFragment) {
11371139
menu.findItem(R.id.sort).setVisible(false);
11381140
} else if (fragment instanceof FtpServerFragment) {
@@ -1156,6 +1158,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
11561158
menu.findItem(R.id.hiddenitems).setVisible(false);
11571159
menu.findItem(R.id.view).setVisible(false);
11581160
menu.findItem(R.id.extract).setVisible(true);
1161+
menu.findItem(R.id.open_in_terminal).setVisible(false);
11591162
invalidatePasteSnackbar(false);
11601163
}
11611164
return super.onPrepareOptionsMenu(menu);
@@ -1291,6 +1294,10 @@ public boolean onOptionsItemSelected(MenuItem item) {
12911294
break;
12921295
case R.id.search:
12931296
getAppbar().getSearchView().revealSearchView();
1297+
break;
1298+
case R.id.open_in_terminal:
1299+
if (getFragmentAtFrame() instanceof MainFragment) {}
1300+
12941301
break;
12951302
}
12961303
return null;

app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ public void requestInstallApkPermission(
178178
isInitialStart);
179179
}
180180

181+
public void requestTerminalPermission() {}
182+
181183
/**
182184
* Requests permission, overrides {@param rationale}'s POSITIVE button dialog action.
183185
*
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.amaze.filemanager.ui.dialogs
2+
3+
import android.content.SharedPreferences
4+
import android.os.Bundle
5+
import android.view.LayoutInflater
6+
import android.view.View
7+
import android.view.ViewGroup
8+
import androidx.preference.PreferenceManager
9+
import androidx.recyclerview.widget.LinearLayoutManager
10+
import com.amaze.filemanager.R
11+
import com.amaze.filemanager.adapters.AppsRecyclerAdapter
12+
import com.amaze.filemanager.adapters.data.AppDataParcelable
13+
import com.amaze.filemanager.adapters.glide.AppsAdapterPreloadModel
14+
import com.amaze.filemanager.adapters.holders.AppHolder
15+
import com.amaze.filemanager.databinding.FragmentOpenFileDialogBinding
16+
import com.amaze.filemanager.ui.activities.MainActivity
17+
import com.amaze.filemanager.ui.base.BaseBottomSheetFragment
18+
import com.amaze.filemanager.ui.fragments.AdjustListViewForTv
19+
import com.amaze.filemanager.utils.GlideConstants
20+
import com.bumptech.glide.Glide
21+
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
22+
import com.bumptech.glide.util.ViewPreloadSizeProvider
23+
24+
abstract class AbstractChooseAppToOpenFragment :
25+
BaseBottomSheetFragment(),
26+
AdjustListViewForTv<AppHolder> {
27+
protected var fragmentOpenFileDialogBinding: FragmentOpenFileDialogBinding? = null
28+
protected val viewBinding get() = fragmentOpenFileDialogBinding!!
29+
30+
private lateinit var adapter: AppsRecyclerAdapter
31+
private lateinit var sharedPreferences: SharedPreferences
32+
33+
override fun onCreate(savedInstanceState: Bundle?) {
34+
super.onCreate(savedInstanceState)
35+
setStyle(STYLE_NORMAL, R.style.appBottomSheetDialogTheme)
36+
}
37+
38+
override fun onCreateView(
39+
inflater: LayoutInflater,
40+
container: ViewGroup?,
41+
savedInstanceState: Bundle?,
42+
): View? {
43+
fragmentOpenFileDialogBinding = FragmentOpenFileDialogBinding.inflate(inflater)
44+
initDialogResources(viewBinding.parent)
45+
return viewBinding.root
46+
}
47+
48+
override fun onViewCreated(
49+
view: View,
50+
savedInstanceState: Bundle?,
51+
) {
52+
super.onViewCreated(view, savedInstanceState)
53+
54+
val modelProvider = AppsAdapterPreloadModel(this, true)
55+
val sizeProvider = ViewPreloadSizeProvider<String>()
56+
val preloader =
57+
RecyclerViewPreloader(
58+
Glide.with(this),
59+
modelProvider,
60+
sizeProvider,
61+
GlideConstants.MAX_PRELOAD_FILES,
62+
)
63+
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
64+
65+
val appDataParcelableList = loadAppList()
66+
67+
adapter =
68+
AppsRecyclerAdapter(
69+
this,
70+
modelProvider,
71+
true,
72+
this,
73+
appDataParcelableList,
74+
)
75+
loadViews()
76+
viewBinding.appsRecyclerView.addOnScrollListener(preloader)
77+
}
78+
79+
override fun onDestroyView() {
80+
super.onDestroyView()
81+
fragmentOpenFileDialogBinding = null
82+
}
83+
84+
override fun onPause() {
85+
super.onPause()
86+
dismiss()
87+
}
88+
89+
private fun loadViews() {
90+
viewBinding.run {
91+
appsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
92+
appsRecyclerView.adapter = adapter
93+
doLoadViewsWith(this)
94+
}
95+
}
96+
97+
protected open fun doLoadViewsWith(viewBinding: FragmentOpenFileDialogBinding) = Unit
98+
99+
protected abstract fun loadAppList(): MutableList<AppDataParcelable>
100+
101+
protected abstract fun initLastAppData(
102+
lastClassAndPackage: List<String>?,
103+
appDataParcelableList: MutableList<AppDataParcelable>,
104+
): AppDataParcelable?
105+
106+
override fun adjustListViewForTv(
107+
viewHolder: AppHolder,
108+
mainActivity: MainActivity,
109+
) {
110+
// do nothing
111+
}
112+
}

app/src/main/java/com/amaze/filemanager/ui/dialogs/OpenFileDialogFragment.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import com.amaze.filemanager.ui.provider.UtilitiesProvider
5454
import com.amaze.filemanager.ui.startActivityCatchingSecurityException
5555
import com.amaze.filemanager.ui.views.ThemedTextView
5656
import com.amaze.filemanager.utils.GlideConstants
57+
import com.amaze.filemanager.utils.queryIntentActivitiesCompat
5758
import com.bumptech.glide.Glide
5859
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
5960
import com.bumptech.glide.util.ViewPreloadSizeProvider
@@ -159,7 +160,7 @@ class OpenFileDialogFragment : BaseBottomSheetFragment(), AdjustListViewForTv<Ap
159160

160161
for (
161162
resolveInfo in context.packageManager
162-
.queryIntentActivities(
163+
.queryIntentActivitiesCompat(
163164
chooserIntent,
164165
PackageManager.MATCH_DEFAULT_ONLY,
165166
)
@@ -300,7 +301,7 @@ class OpenFileDialogFragment : BaseBottomSheetFragment(), AdjustListViewForTv<Ap
300301
inflater: LayoutInflater,
301302
container: ViewGroup?,
302303
savedInstanceState: Bundle?,
303-
): View? {
304+
): View {
304305
fragmentOpenFileDialogBinding = FragmentOpenFileDialogBinding.inflate(inflater)
305306
initDialogResources(viewBinding.parent)
306307
return viewBinding.root
@@ -408,7 +409,7 @@ class OpenFileDialogFragment : BaseBottomSheetFragment(), AdjustListViewForTv<Ap
408409
private fun initAppDataParcelableList(intent: Intent): MutableList<AppDataParcelable> {
409410
val packageManager = requireContext().packageManager
410411
val appDataParcelableList: MutableList<AppDataParcelable> = ArrayList()
411-
packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL).forEach {
412+
packageManager.queryIntentActivitiesCompat(intent, PackageManager.MATCH_ALL).forEach {
412413
val openFileParcelable =
413414
OpenFileParcelable(
414415
uri,

0 commit comments

Comments
 (0)