Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi user file browsing, closes #2479 #2482

Merged
merged 13 commits into from
Dec 22, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -653,24 +653,16 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) {
return true;
}
case R.id.action_toggle_case:
if (_hlEditor != null) {
_hlEditor.toggleCase();
}
TextViewUtils.toggleSelectionCase(_hlEditor.getText());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleanups to how these are structured and organized

return true;
case R.id.action_switch_case:
if (_hlEditor != null) {
_hlEditor.switchCase();
}
TextViewUtils.switchSelectionCase(_hlEditor.getText());
return true;
case R.id.action_capitalize_words:
if (_hlEditor != null) {
_hlEditor.capitalizeWords();
}
TextViewUtils.capitalizeSelectionWords(_hlEditor.getText());
return true;
case R.id.action_capitalize_sentences:
if (_hlEditor != null) {
_hlEditor.capitalizeSentences();
}
TextViewUtils.capitalizeSelectionSentences(_hlEditor.getText());
return true;
default: {
return super.onOptionsItemSelected(item);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ public void onActivityFirstTimeVisible() {
}
}


@Override
public void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState);
Expand Down Expand Up @@ -334,7 +333,7 @@ public void onBackPressed() {
}

public String getFileBrowserTitle() {
final File file = _notebook.getCurrentFolder();
final File file = _notebook != null ? _notebook.getCurrentFolder() : null;
if (file != null && !_appSettings.getNotebookDirectory().equals(file)) {
return "> " + file.getName();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package net.gsantner.markor.frontend.filebrowser;

import android.content.Context;
import android.os.Environment;

import androidx.fragment.app.FragmentManager;

Expand All @@ -16,6 +17,7 @@
import net.gsantner.markor.model.AppSettings;
import net.gsantner.markor.util.MarkorContextUtils;
import net.gsantner.opoc.frontend.filebrowser.GsFileBrowserDialog;
import net.gsantner.opoc.frontend.filebrowser.GsFileBrowserListAdapter;
import net.gsantner.opoc.frontend.filebrowser.GsFileBrowserOptions;
import net.gsantner.opoc.util.GsContextUtils;
import net.gsantner.opoc.wrapper.GsCallback;
Expand All @@ -41,6 +43,7 @@ public static GsFileBrowserOptions.Options prepareFsViewerOpts(
if (listener != null) {
opts.listener = listener;
}

opts.doSelectFolder = doSelectFolder;
opts.doSelectFile = !doSelectFolder;

Expand All @@ -67,29 +70,50 @@ public static GsFileBrowserOptions.Options prepareFsViewerOpts(
opts.folderColor = R.color.folder;
opts.fileImage = R.drawable.ic_file_white_24dp;
opts.folderImage = R.drawable.ic_folder_white_24dp;
opts.descriptionFormat = appSettings.getString(R.string.pref_key__file_description_format, "");

opts.titleText = R.string.select;

opts.mountedStorageFolder = cu.getStorageAccessFolder(context);

opts.refresh = () -> {
opts.sortFolderFirst = appSettings.isFileBrowserSortFolderFirst();
opts.sortByType = appSettings.getFileBrowserSortByType();
opts.sortReverse = appSettings.isFileBrowserSortReverse();
opts.filterShowDotFiles = appSettings.isFileBrowserFilterShowDotFiles();
opts.favouriteFiles = appSettings.getFavouriteFiles();
opts.recentFiles = appSettings.getRecentFiles();
opts.popularFiles = appSettings.getPopularFiles();
opts.storageMaps.clear();
opts.storageMaps.put(new File("/storage", cu.rstr(context, R.string.notebook)), appSettings.getNotebookDirectory());
opts.storageMaps.put(new File("/storage/Download"), new File("/storage/emulated/0/Download"));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Download folder resolved using API now

};
opts.refresh.callback();
updateFsViewerOpts(opts, context, appSettings);

return opts;
}

public static void updateFsViewerOpts(
final GsFileBrowserOptions.Options opts,
final Context context,
AppSettings appSettings
) {
appSettings = appSettings != null ? appSettings : ApplicationObject.settings();

opts.sortFolderFirst = appSettings.isFileBrowserSortFolderFirst();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These don't really need to be refreshed dynamically

opts.sortByType = appSettings.getFileBrowserSortByType();
opts.sortReverse = appSettings.isFileBrowserSortReverse();
opts.filterShowDotFiles = appSettings.isFileBrowserFilterShowDotFiles();
opts.favouriteFiles = appSettings.getFavouriteFiles();
opts.recentFiles = appSettings.getRecentFiles();
opts.popularFiles = appSettings.getPopularFiles();

opts.descriptionFormat = appSettings.getString(R.string.pref_key__file_description_format, "");

opts.storageMaps.clear();
opts.iconMaps.clear();

final File downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
opts.addVirtualFile("Download", downloads, R.drawable.baseline_download_24);

final File notebook = appSettings.getNotebookDirectory();
opts.addVirtualFile(context.getString(R.string.notebook), notebook, R.drawable.ic_home_black_24dp);

opts.iconMaps.put(GsFileBrowserListAdapter.VIRTUAL_STORAGE_FAVOURITE, R.drawable.ic_star_black_24dp);
opts.iconMaps.put(GsFileBrowserListAdapter.VIRTUAL_STORAGE_RECENTS, R.drawable.ic_history_black_24dp);
opts.iconMaps.put(GsFileBrowserListAdapter.VIRTUAL_STORAGE_POPULAR, R.drawable.ic_favorite_black_24dp);
opts.iconMaps.put(notebook, R.drawable.ic_home_black_24dp);
opts.iconMaps.put(downloads, R.drawable.baseline_download_24);
opts.iconMaps.put(appSettings.getQuickNoteFile(), R.drawable.ic_lightning_black_24dp);
opts.iconMaps.put(appSettings.getTodoFile(), R.drawable.ic_assignment_turned_in_black_24dp);
}


public static File[] strlistToArray(List<String> strlist) {
File[] files = new File[strlist.size()];
for (int i = 0; i < files.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@
import net.gsantner.opoc.format.GsTextUtils;
import net.gsantner.opoc.wrapper.GsCallback;
import net.gsantner.opoc.wrapper.GsTextWatcherAdapter;
import net.gsantner.markor.util.TextCasingUtils;

import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
Expand Down Expand Up @@ -320,60 +318,6 @@ private int rowEnd(final int y) {
return layout == null ? 0 : layout.getLineEnd(layout.getLineForVertical(y));
}

// Text-Casing
// ---------------------------------------------------------------------------------------------
public void toggleCase() {
String text = getSelectedText();
if (text.isEmpty()) {
text = Objects.requireNonNull(getText()).toString();
}
String newText = TextCasingUtils.toggleCase(text);
replaceSelection(newText);
}

public void switchCase() {
String text = getSelectedText();
if (text.isEmpty()) {
text = Objects.requireNonNull(getText()).toString();
}
String newText = TextCasingUtils.switchCase(text);
replaceSelection(newText);
}

public void capitalizeWords() {
String text = getSelectedText();
if (text.isEmpty()) {
text = Objects.requireNonNull(getText()).toString();
}
String newText = TextCasingUtils.capitalizeWords(text);
replaceSelection(newText);
}

public void capitalizeSentences() {
String text = getSelectedText();
if (text.isEmpty()) {
text = Objects.requireNonNull(getText()).toString();
}
String newText = TextCasingUtils.capitalizeSentences(text);
replaceSelection(newText);
}

private String getSelectedText() {
int start = Math.max(0, getSelectionStart());
int end = Math.max(0, getSelectionEnd());
return Objects.requireNonNull(getText()).toString().substring(start, end);
}

private void replaceSelection(String replacement) {
int start = Math.max(0, getSelectionStart());
int end = Math.max(0, getSelectionEnd());
if (start == end) { // If no selection is made, replace all the text in the document
setText(replacement);
} else { // Replace only the selected text
Objects.requireNonNull(getText()).replace(start, end, replacement);
}
}

// Various overrides
// ---------------------------------------------------------------------------------------------
public void setSaveInstanceState(final boolean save) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import androidx.annotation.NonNull;

import net.gsantner.markor.util.TextCasingUtils;
import net.gsantner.opoc.format.GsTextUtils;
import net.gsantner.opoc.util.GsContextUtils;

Expand All @@ -40,7 +41,7 @@
import java.util.TreeSet;
import java.util.UUID;

@SuppressWarnings({"CharsetObjectCanBeUsed", "WeakerAccess", "unused"})
@SuppressWarnings({"WeakerAccess", "unused"})
public final class TextViewUtils {

// Suppress default constructor for noninstantiability
Expand Down Expand Up @@ -128,15 +129,24 @@ public static int[] getSelection(final CharSequence text) {
}
}

public static String getSelectedText(final CharSequence text) {
public static CharSequence getSelectedText(final CharSequence text) {
final int[] sel = getSelection(text);
return (sel[0] >= 0 && sel[1] >= 0) ? text.subSequence(sel[0], sel[1]).toString() : "";
return (sel[0] >= 0 && sel[1] >= 0) ? text.subSequence(sel[0], sel[1]) : "";
}

public static String getSelectedText(final TextView text) {
public static CharSequence getSelectedText(final TextView text) {
return getSelectedText(text.getText());
}

public static void replaceSelection(final Editable text, final CharSequence replace) {
if (text != null && replace != null) {
final int[] sel = getSelection(text);
if (sel[0] >= 0 && sel[1] >= 0) {
text.replace(sel[0], sel[1], replace);
}
}
}

public static int[] getLineSelection(final CharSequence text, final int[] sel) {
return sel != null && sel.length >= 2 ? new int[]{getLineStart(text, sel[0]), getLineEnd(text, sel[1])} : new int[]{-1, -1};
}
Expand Down Expand Up @@ -380,7 +390,7 @@ public static void setSelectionAndShow(final EditText edit, final int... sel) {
* @param title Title of note (for {{title}})
* @param selectedText Currently selected text
*/
public static String interpolateSnippet(String text, final String title, final String selectedText) {
public static String interpolateSnippet(String text, final CharSequence title, final CharSequence selectedText) {
final long current = System.currentTimeMillis();
final String time = GsContextUtils.instance.formatDateTime((Locale) null, "HH:mm", current);
final String date = GsContextUtils.instance.formatDateTime((Locale) null, "yyyy-MM-dd", current);
Expand Down Expand Up @@ -753,4 +763,34 @@ public static Boolean isImeOpen(final View view) {
}
return null; // Uncertain
}

// Text-Casing
// ---------------------------------------------------------------------------------------------
public static void toggleSelectionCase(final Editable edit) {
final String text = getSelectedText(edit).toString();
if (!text.isEmpty()) {
replaceSelection(edit, TextCasingUtils.toggleCase(text));
}
}

public static void switchSelectionCase(final Editable edit) {
final String text = getSelectedText(edit).toString();
if (!text.isEmpty()) {
replaceSelection(edit, TextCasingUtils.switchCase(text));
}
}

public static void capitalizeSelectionWords(final Editable edit) {
final String text = getSelectedText(edit).toString();
if (!text.isEmpty()) {
replaceSelection(edit, TextCasingUtils.capitalizeWords(text));
}
}

public static void capitalizeSelectionSentences(final Editable edit) {
final String text = getSelectedText(edit).toString();
if (!text.isEmpty()) {
replaceSelection(edit, TextCasingUtils.capitalizeSentences(text));
}
}
}
2 changes: 0 additions & 2 deletions app/src/main/java/net/gsantner/markor/model/AppSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ public class AppSettings extends GsSharedPreferencesPropertyBackend {
public static Boolean _isDeviceGoodHardware = null;
private MarkorContextUtils _cu;

private static final File LOCAL_TESTFOLDER_FILEPATH = new File("/storage/emulated/0/00_sync/documents/special");

@Override
public AppSettings init(final Context context) {
super.init(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,12 @@ public void onViewCreated(final View root, final @Nullable Bundle savedInstanceS

_filesystemViewerAdapter = new GsFileBrowserListAdapter(_dopt, activity);
_recyclerList.setAdapter(_filesystemViewerAdapter);
onFsViewerDoUiUpdate(_filesystemViewerAdapter);

// Setup callbacks
_dopt.setSubtitle = _toolBar::setSubtitle;
_dopt.setTitle = _toolBar::setTitle;

_recyclerList.post(() -> onFsViewerDoUiUpdate(_filesystemViewerAdapter));
}

private int rcolor(@ColorRes int colorRes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ public static GsFileBrowserFragment newInstance() {
private Menu _fragmentMenu;
private MarkorContextUtils _cu;
private Toolbar _toolbar;
private File _lastSelectedFile;

//########################
//## Methods
Expand Down Expand Up @@ -207,6 +206,11 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) {
if (_callback != null) {
_callback.onFsViewerConfig(dopt);
}

final Context context = getContext();
if (context != null) {
MarkorFileBrowserFactory.updateFsViewerOpts(dopt, context, _appSettings);
}
}

@Override
Expand Down Expand Up @@ -235,7 +239,7 @@ private void updateMenuItems() {
// Check if is a favourite
boolean selTextFilesOnly = true;
boolean selDirectoriesOnly = true;
boolean selWritable = (!curFilepath.equals("/storage") && !curFilepath.equals("/storage/emulated"));
boolean selWritable = true;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't hardcode these like this now

boolean allSelectedFav = true;
final Collection<File> favFiles = _dopt.favouriteFiles != null ? _dopt.favouriteFiles : Collections.emptySet();
for (final File f : selFiles) {
Expand Down Expand Up @@ -314,10 +318,7 @@ public void onViewStateRestored(final Bundle savedInstanceState) {
@Override
public void onResume() {
super.onResume();
if (_dopt.refresh != null) {
_dopt.refresh.callback();
}

_dopt.listener.onFsViewerConfig(_dopt);
final File folder = getCurrentFolder();
final Activity activity = getActivity();
if (isVisible() && folder != null && activity != null) {
Expand Down
Loading
Loading