From 34f98b916f60db40872d24281cd8ab19a9c5f56e Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Thu, 2 Jan 2025 22:26:46 -0800 Subject: [PATCH 01/12] Initial system with janky ui --- .../gsantner/markor/model/AppSettings.java | 96 +++++++++++++++---- .../net/gsantner/markor/model/Document.java | 12 +-- .../filebrowser/GsFileBrowserDialog.java | 7 ++ .../filebrowser/GsFileBrowserFragment.java | 41 ++++++++ .../filebrowser/GsFileBrowserListAdapter.java | 11 ++- .../filebrowser/GsFileBrowserOptions.java | 7 ++ .../GsSharedPreferencesPropertyBackend.java | 8 ++ .../gsantner/opoc/util/GsContextUtils.java | 6 +- .../net/gsantner/opoc/util/GsFileUtils.java | 10 ++ app/src/main/res/menu/filesystem__menu.xml | 6 ++ 10 files changed, 168 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index 844ec7cb86..2a434a7759 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -13,6 +13,7 @@ import android.graphics.Color; import android.os.Build; import android.os.Environment; +import android.text.TextUtils; import android.util.Pair; import androidx.annotation.ColorRes; @@ -44,6 +45,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -85,7 +87,7 @@ public boolean isPreferViewMode() { } public void setNotebookDirectory(final File file) { - setString(R.string.pref_key__notebook_directory, Document.getPath(file)); + setString(R.string.pref_key__notebook_directory, GsFileUtils.getPath(file)); } public File getNotebookDirectory() { @@ -104,7 +106,7 @@ public File getQuickNoteFile() { } public void setQuickNoteFile(final File file) { - setString(R.string.pref_key__quicknote_filepath, Document.getPath(file)); + setString(R.string.pref_key__quicknote_filepath, GsFileUtils.getPath(file)); } public File getDefaultQuickNoteFile() { @@ -116,7 +118,7 @@ public File getTodoFile() { } public void setTodoFile(final File file) { - setString(R.string.pref_key__todo_filepath, Document.getPath(file)); + setString(R.string.pref_key__todo_filepath, GsFileUtils.getPath(file)); } public File getDefaultTodoFile() { @@ -130,7 +132,7 @@ public File getSnippetsDirectory() { } public void setSnippetDirectory(final File folder) { - setString(R.string.pref_key__snippet_directory_path, Document.getPath(folder)); + setString(R.string.pref_key__snippet_directory_path, GsFileUtils.getPath(folder)); } public String getFontFamily() { @@ -259,6 +261,62 @@ public boolean isRecreateMainRequired() { return ret; } + private final String PREF_PREFIX_FOLDER_SORT_ORDER = "PREF_PREFIX_FOLDER_SORT_ORDER"; + + public static class FolderSortOrder { + private final static String SORT_BY_KEY = "SORT_BY"; + private final static String REVERSE_KEY = "REVERSE"; + private final static String SHOW_DOT_FILES_KEY = "SHOW_DOT_FILES"; + private final static String FOLDER_FIRST_KEY = "FOLDER_FIRST"; + + public String sortByType = GsFileUtils.SORT_BY_NAME; + public boolean reverse = false; + public boolean showDotFiles = false; + public boolean folderFirst = true; + } + + public void setFolderSortOrder(final String canonicalPath, final @Nullable FolderSortOrder sortOrder) { + if (TextUtils.isEmpty(canonicalPath)) { + return; + } + + final String key = PREF_PREFIX_FOLDER_SORT_ORDER + canonicalPath; + + if (sortOrder == null) { + remove(key); + return; + } + + final Map order = new HashMap<>(); + order.put(FolderSortOrder.SORT_BY_KEY, sortOrder.sortByType != null ? sortOrder.sortByType : GsFileUtils.SORT_BY_NAME); + order.put(FolderSortOrder.REVERSE_KEY, String.valueOf(sortOrder.reverse)); + order.put(FolderSortOrder.SHOW_DOT_FILES_KEY, String.valueOf(sortOrder.showDotFiles)); + order.put(FolderSortOrder.FOLDER_FIRST_KEY, String.valueOf(sortOrder.folderFirst)); + + setString(key, mapToJsonString(order)); + } + + public @Nullable FolderSortOrder getFolderSortOrder(final String canonicalPath) { + if (TextUtils.isEmpty(canonicalPath)) { + return null; + } + + final String key = PREF_PREFIX_FOLDER_SORT_ORDER + canonicalPath; + final String json = getString(key, null); + if (json == null) { + return null; + } + final Map order = jsonStringToMap(getString(key, "{}")); + + final FolderSortOrder sortOrder = new FolderSortOrder(); + sortOrder.sortByType = order.get(FolderSortOrder.SORT_BY_KEY); + sortOrder.reverse = Boolean.parseBoolean(order.get(FolderSortOrder.REVERSE_KEY)); + sortOrder.showDotFiles = Boolean.parseBoolean(order.get(FolderSortOrder.SHOW_DOT_FILES_KEY)); + sortOrder.folderFirst = Boolean.parseBoolean(order.get(FolderSortOrder.FOLDER_FIRST_KEY)); + + return sortOrder; + } + public String setFileBrowserSortByType(String v) { setString(R.string.pref_key__file_browser__sort_by_type, v); return v; @@ -338,12 +396,12 @@ public void addRecentFile(final File file) { if (!listFileInRecents(file)) { return; } - final String path = Document.getPath(file); + final String path = GsFileUtils.getPath(file); if (!file.equals(getTodoFile()) && !file.equals(getQuickNoteFile())) { ArrayList recent = getRecentDocuments(); recent.add(0, path); - recent.remove(Document.getPath(getTodoFile())); - recent.remove(Document.getPath(getQuickNoteFile())); + recent.remove(GsFileUtils.getPath(getTodoFile())); + recent.remove(GsFileUtils.getPath(getQuickNoteFile())); recent.remove(""); recent.remove(null); @@ -357,7 +415,7 @@ public void setFavouriteFiles(final Collection files) { final Set set = new LinkedHashSet<>(); for (final File f : files) { if (f != null && (f.exists() || GsFileBrowserListAdapter.isVirtualFolder(f))) { - set.add(Document.getPath(f)); + set.add(GsFileUtils.getPath(f)); } } setStringList(R.string.pref_key__favourite_files, GsCollectionUtils.map(set, p -> p)); @@ -421,8 +479,8 @@ public void setLastViewPosition(File file, int scrollX, int scrollY) { return; } if (!file.equals(getTodoFile()) && !file.equals(getQuickNoteFile())) { - setInt(PREF_PREFIX_VIEW_SCROLL_X + Document.getPath(file), scrollX, _prefCache); - setInt(PREF_PREFIX_VIEW_SCROLL_Y + Document.getPath(file), scrollY, _prefCache); + setInt(PREF_PREFIX_VIEW_SCROLL_X + GsFileUtils.getPath(file), scrollX, _prefCache); + setInt(PREF_PREFIX_VIEW_SCROLL_Y + GsFileUtils.getPath(file), scrollY, _prefCache); } } @@ -549,14 +607,14 @@ public int getLastViewPositionX(File file) { if (file == null || !file.exists()) { return -1; } - return getInt(PREF_PREFIX_VIEW_SCROLL_X + Document.getPath(file), -3, _prefCache); + return getInt(PREF_PREFIX_VIEW_SCROLL_X + GsFileUtils.getPath(file), -3, _prefCache); } public int getLastViewPositionY(File file) { if (file == null || !file.exists()) { return -1; } - return getInt(PREF_PREFIX_VIEW_SCROLL_Y + Document.getPath(file), -3, _prefCache); + return getInt(PREF_PREFIX_VIEW_SCROLL_Y + GsFileUtils.getPath(file), -3, _prefCache); } private List getPopularDocumentsSorted() { @@ -800,16 +858,16 @@ public int getTabWidth() { } public boolean listFileInRecents(File file) { - return getBool(Document.getPath(file) + "_list_in_recents", true); + return getBool(GsFileUtils.getPath(file) + "_list_in_recents", true); } public void setListFileInRecents(File file, boolean value) { - setBool(Document.getPath(file) + "_list_in_recents", value); + setBool(GsFileUtils.getPath(file) + "_list_in_recents", value); if (!value) { ArrayList recent = getRecentDocuments(); - if (recent.contains(Document.getPath(file))) { - recent.remove(Document.getPath(file)); + if (recent.contains(GsFileUtils.getPath(file))) { + recent.remove(GsFileUtils.getPath(file)); setRecentDocuments(recent); } } @@ -824,11 +882,11 @@ public ArrayList getFilesTaggedWith(String tag) { }*/ public int getRating(File file) { - return getInt(Document.getPath(file) + "_rating", 0); + return getInt(GsFileUtils.getPath(file) + "_rating", 0); } public void setRating(File file, int value) { - setInt(Document.getPath(file) + "_rating", value); + setInt(GsFileUtils.getPath(file) + "_rating", value); } public boolean isEditorLineBreakingEnabled() { @@ -918,7 +976,7 @@ public void setNewFileDialogLastUsedType(final int format) { } public void setFileBrowserLastBrowsedFolder(File f) { - setString(R.string.pref_key__file_browser_last_browsed_folder, Document.getPath(f)); + setString(R.string.pref_key__file_browser_last_browsed_folder, GsFileUtils.getPath(f)); } public File getFileBrowserLastBrowsedFolder() { diff --git a/app/src/main/java/net/gsantner/markor/model/Document.java b/app/src/main/java/net/gsantner/markor/model/Document.java index e4003c5194..0541b6d392 100644 --- a/app/src/main/java/net/gsantner/markor/model/Document.java +++ b/app/src/main/java/net/gsantner/markor/model/Document.java @@ -72,7 +72,7 @@ public class Document implements Serializable { private int _lastLength = -1; public Document(@NonNull final File f) { - path = getPath(f); + path = GsFileUtils.getPath(f); file = new File(path); title = GsFileUtils.getFilenameWithoutExtension(file); extension = GsFileUtils.getFilenameExtension(file); @@ -86,16 +86,6 @@ public Document(@NonNull final File f) { } } - public static String getPath(final File file) { - try { - return file.getCanonicalPath(); - } catch (IOException e) { - return file.getAbsolutePath(); - } catch (NullPointerException e) { - return ""; - } - } - // Get a default file public static Document getDefault(final Context context) { final File notebook = ApplicationObject.settings().getNotebookDirectory(); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java index c58f2311fe..47b5994f73 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java @@ -310,6 +310,13 @@ public void onFsViewerItemLongPressed(File file, boolean doSelectMultiple) { } } + @Override + public void onFsViewerFolderChanged(File newFolder) { + if (_callback != null) { + _callback.onFsViewerFolderChanged(newFolder); + } + } + @Override public void onStart() { super.onStart(); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java index c9a6f46ebc..e1e2c8abb6 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java @@ -21,6 +21,7 @@ import android.app.Activity; import android.content.Context; import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Pair; import android.view.Menu; @@ -178,6 +179,31 @@ private void checkOptions() { } } + @Override + public void onFsViewerFolderChanged(final File newFolder) { + if (_callback != null) { + _callback.onFsViewerFolderChanged(newFolder); + } + + final AppSettings.FolderSortOrder order = _appSettings.getFolderSortOrder(GsFileUtils.getPath(newFolder)); + if (order != null) { + _dopt.sortByType = order.sortByType; + _dopt.sortFolderFirst = order.folderFirst; + _dopt.sortReverse = order.reverse; + _dopt.filterShowDotFiles = order.showDotFiles; + } else { + _dopt.sortByType = _appSettings.getFileBrowserSortByType(); + _dopt.sortFolderFirst = _appSettings.isFileBrowserSortFolderFirst(); + _dopt.sortReverse = _appSettings.isFileBrowserSortReverse(); + _dopt.filterShowDotFiles = _appSettings.isFileBrowserFilterShowDotFiles(); + } + + // final MenuItem sortItem = _fragmentMenu.findItem(R.id.action_sort); + // if (sortItem != null) { + // sortItem.setChecked(order != null); + // _cu.tintDrawable(sortItem.getIcon(), order != null ? 0xFFE3B51B : Color.WHITE); + // } + } @Override public void onFsViewerSelected(String request, File file, final Integer lineNumber) { @@ -510,6 +536,21 @@ public boolean onOptionsItemSelected(final MenuItem item) { } return true; } + case R.id.action_save_sort_settings: { + item.setChecked(!item.isChecked()); + final AppSettings.FolderSortOrder order; + if (item.isChecked()) { + order = new AppSettings.FolderSortOrder(); + order.sortByType = _dopt.sortByType; + order.folderFirst = _dopt.sortFolderFirst; + order.reverse = _dopt.sortReverse; + order.showDotFiles = _dopt.filterShowDotFiles; + } else { + order = null; + } + _appSettings.setFolderSortOrder(GsFileUtils.getPath(getCurrentFolder()), order); + return true; + } } return false; diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java index 8cb5b9bc8f..c8afb7fcb0 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java @@ -247,7 +247,7 @@ public void onBindViewHolder(@NonNull FilesystemViewerViewHolder holder, int pos android.graphics.PorterDuff.Mode.SRC_ATOP ); - if (!isSelected && isFavourite) { + if (!isSelected && !isGoUp && isFavourite) { holder.image.setColorFilter(0xFFE3B51B); } @@ -662,6 +662,10 @@ private void loadFolder(final File folder, final File show) { _currentFolder = GsCollectionUtils.getOrDefault(_virtualMapping, folder, folder); } + if (folderChanged) { + _dopt.listener.onFsViewerFolderChanged(_currentFolder); + } + if (_currentFolder != null) { final File toShow = show == null ? _fileToShowAfterNextLoad : show; _fileToShowAfterNextLoad = null; @@ -709,10 +713,7 @@ private synchronized void _loadFolder(final boolean folderChanged, final @Nullab GsCollectionUtils.deduplicate(newData); - // Don't sort recent or virtual root items - use the default order - if (!Arrays.asList(VIRTUAL_STORAGE_RECENTS, VIRTUAL_STORAGE_ROOT).contains(_currentFolder)) { - GsFileUtils.sortFiles(newData, _dopt.sortByType, _dopt.sortFolderFirst, _dopt.sortReverse); - } + GsFileUtils.sortFiles(newData, _dopt.sortByType, _dopt.sortFolderFirst, _dopt.sortReverse); // Testing if modtimes have changed (modtimes generally only increase) final long modSum = GsCollectionUtils.accumulate(newData, (f, s) -> s + f.lastModified(), 0L); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java index 4f1df3cb4a..a71f7281d3 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java @@ -41,6 +41,8 @@ public interface SelectionListener { void onFsViewerDoUiUpdate(final GsFileBrowserListAdapter adapter); void onFsViewerItemLongPressed(final File file, boolean doSelectMultiple); + + void onFsViewerFolderChanged(final File newFolder); } public static class Options { @@ -166,5 +168,10 @@ public void onFsViewerDoUiUpdate(GsFileBrowserListAdapter adapter) { public void onFsViewerItemLongPressed(File file, boolean doSelectMultiple) { } + + @Override + public void onFsViewerFolderChanged(File newFolder) { + + } } } diff --git a/app/src/main/java/net/gsantner/opoc/model/GsSharedPreferencesPropertyBackend.java b/app/src/main/java/net/gsantner/opoc/model/GsSharedPreferencesPropertyBackend.java index 190bd28b3b..3250639d0b 100644 --- a/app/src/main/java/net/gsantner/opoc/model/GsSharedPreferencesPropertyBackend.java +++ b/app/src/main/java/net/gsantner/opoc/model/GsSharedPreferencesPropertyBackend.java @@ -566,6 +566,14 @@ public boolean contains(String key, final SharedPreferences... pref) { return gp(pref).contains(key); } + public void remove(@StringRes int keyResourceId, final SharedPreferences... pref) { + gp(pref).edit().remove(rstr(keyResourceId)).apply(); + } + + public void remove(final String key, final SharedPreferences... pref) { + gp(pref).edit().remove(key).apply(); + } + /** * Substract current datetime by given amount of days */ diff --git a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java index 7bff4dad0c..8ffe688ae0 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java @@ -870,7 +870,11 @@ public Bitmap drawTextOnDrawable(final Context context, @DrawableRes final int d /** * Try to tint all {@link Menu}s {@link MenuItem}s with given color */ - public void tintMenuItems(final Menu menu, final boolean recurse, @ColorInt final int iconColor) { + public void tintMenuItems(final @Nullable Menu menu, final boolean recurse, @ColorInt final int iconColor) { + if (menu == null) { + return; + } + for (int i = 0; i < menu.size(); i++) { MenuItem item = menu.getItem(i); try { diff --git a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java index 87a9ebf9ab..3b1eb88a35 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java @@ -74,6 +74,16 @@ public class GsFileUtils { private final static int BUFFER_SIZE = 4096; private final static Map MIME_TYPE_CACHE = new ConcurrentHashMap<>(); + public static String getPath(final File file) { + try { + return file.getCanonicalPath(); + } catch (IOException e) { + return file.getAbsolutePath(); + } catch (NullPointerException e) { + return ""; + } + } + /** * Info of various types about a file */ diff --git a/app/src/main/res/menu/filesystem__menu.xml b/app/src/main/res/menu/filesystem__menu.xml index f8d3347d9b..26e2290a76 100644 --- a/app/src/main/res/menu/filesystem__menu.xml +++ b/app/src/main/res/menu/filesystem__menu.xml @@ -135,6 +135,12 @@ android:title="@string/dotfiles" app:showAsAction="never" /> + From a02026d84840d56dac404e92beb5b32fec6471b4 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Fri, 3 Jan 2025 14:25:20 -0800 Subject: [PATCH 02/12] Separate options - aborting --- .../filebrowser/MarkorFileBrowserFactory.java | 8 +- .../gsantner/markor/model/AppSettings.java | 111 +++++++---------- .../filebrowser/GsFileBrowserDialog.java | 4 +- .../filebrowser/GsFileBrowserFragment.java | 112 ++++++++++-------- .../filebrowser/GsFileBrowserListAdapter.java | 3 +- .../filebrowser/GsFileBrowserOptions.java | 4 +- .../net/gsantner/opoc/util/GsFileUtils.java | 20 ++-- .../writeily/widget/WrFilesWidgetFactory.java | 11 +- 8 files changed, 132 insertions(+), 141 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java b/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java index 1572157712..89994a8975 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java @@ -85,10 +85,10 @@ public static void updateFsViewerOpts( ) { appSettings = appSettings != null ? appSettings : ApplicationObject.settings(); - opts.sortFolderFirst = appSettings.isFileBrowserSortFolderFirst(); - opts.sortByType = appSettings.getFileBrowserSortByType(); - opts.sortReverse = appSettings.isFileBrowserSortReverse(); - opts.filterShowDotFiles = appSettings.isFileBrowserFilterShowDotFiles(); + opts.sortFolderFirst = appSettings.getFileBrowserSortFolderFirst(null); + opts.sortByType = appSettings.getFileBrowserSortByType(null); + opts.sortReverse = appSettings.getFileBrowserSortReverse(null); + opts.filterShowDotFiles = appSettings.getFileBrowserFilterShowDotFiles(null); opts.favouriteFiles = appSettings.getFavouriteFiles(); opts.recentFiles = appSettings.getRecentFiles(); opts.popularFiles = appSettings.getPopularFiles(); diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index 736e785119..d726d39f1d 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -45,7 +45,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -261,87 +260,73 @@ public boolean isRecreateMainRequired() { return ret; } - private final String PREF_PREFIX_FOLDER_SORT_ORDER = "PREF_PREFIX_FOLDER_SORT_ORDER"; + private final String PREF_PREFIX_FOLDER_SORT_TYPE = "PREF_PREFIX_FOLDER_SORT_TYPE"; + private final String PREF_PREFIX_FOLDER_SORT_REVERSE = "PREF_PREFIX_FOLDER_SORT_REVERSE"; + private final String PREF_PREFIX_FOLDER_SORT_SHOW_DOT = "PREF_PREFIX_FOLDER_SORT_SHOW_DOT"; + private final String PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST = "PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST"; - public static class FolderSortOrder { - private final static String SORT_BY_KEY = "SORT_BY"; - private final static String REVERSE_KEY = "REVERSE"; - private final static String SHOW_DOT_FILES_KEY = "SHOW_DOT_FILES"; - private final static String FOLDER_FIRST_KEY = "FOLDER_FIRST"; - - public String sortByType = GsFileUtils.SORT_BY_NAME; - public boolean reverse = false; - public boolean showDotFiles = false; - public boolean folderFirst = true; + private String cleanPath(final String path) { + return GsTextUtils.isNullOrEmpty(path) ? "" : path.trim(); } - public void setFolderSortOrder(final String canonicalPath, final @Nullable FolderSortOrder sortOrder) { - if (TextUtils.isEmpty(canonicalPath)) { - return; - } + public String setFileBrowserSortByType(final String path, final String type) { + setString(PREF_PREFIX_FOLDER_SORT_TYPE + cleanPath(path), type); + return type; + } - final String key = PREF_PREFIX_FOLDER_SORT_ORDER + canonicalPath; + public String getFileBrowserSortByType(final String path) { + return getString(PREF_PREFIX_FOLDER_SORT_TYPE + cleanPath(path), getString(PREF_PREFIX_FOLDER_SORT_TYPE, GsFileUtils.SORT_BY_NAME)); + } - if (sortOrder == null) { - remove(key); - return; + public void clearFileBrowserSortByType(final String path) { + if (!GsTextUtils.isNullOrEmpty(path.trim())) { + remove(PREF_PREFIX_FOLDER_SORT_TYPE + cleanPath(path)); } + } - final Map order = new HashMap<>(); - order.put(FolderSortOrder.SORT_BY_KEY, sortOrder.sortByType != null ? sortOrder.sortByType : GsFileUtils.SORT_BY_NAME); - order.put(FolderSortOrder.REVERSE_KEY, String.valueOf(sortOrder.reverse)); - order.put(FolderSortOrder.SHOW_DOT_FILES_KEY, String.valueOf(sortOrder.showDotFiles)); - order.put(FolderSortOrder.FOLDER_FIRST_KEY, String.valueOf(sortOrder.folderFirst)); - - setString(key, mapToJsonString(order)); + public boolean setFileBrowserSortReverse(final String path, final boolean value) { + setBool(PREF_PREFIX_FOLDER_SORT_REVERSE + cleanPath(path), value); + return value; } - public @Nullable FolderSortOrder getFolderSortOrder(final String canonicalPath) { - if (TextUtils.isEmpty(canonicalPath)) { - return null; - } + public boolean getFileBrowserSortReverse(final String path) { + return getBool(PREF_PREFIX_FOLDER_SORT_REVERSE + cleanPath(path), getBool(PREF_PREFIX_FOLDER_SORT_REVERSE, false)); + } - final String key = PREF_PREFIX_FOLDER_SORT_ORDER + canonicalPath; - final String json = getString(key, null); - if (json == null) { - return null; + public void clearFileBrowserSortReverse(final String path) { + if (!GsTextUtils.isNullOrEmpty(path.trim())) { + remove(PREF_PREFIX_FOLDER_SORT_REVERSE + cleanPath(path)); } - final Map order = jsonStringToMap(getString(key, "{}")); - - final FolderSortOrder sortOrder = new FolderSortOrder(); - sortOrder.sortByType = order.get(FolderSortOrder.SORT_BY_KEY); - sortOrder.reverse = Boolean.parseBoolean(order.get(FolderSortOrder.REVERSE_KEY)); - sortOrder.showDotFiles = Boolean.parseBoolean(order.get(FolderSortOrder.SHOW_DOT_FILES_KEY)); - sortOrder.folderFirst = Boolean.parseBoolean(order.get(FolderSortOrder.FOLDER_FIRST_KEY)); - - return sortOrder; } - public String setFileBrowserSortByType(String v) { - setString(R.string.pref_key__file_browser__sort_by_type, v); + public boolean setFileBrowserFilterShowDotFiles(final String path, final boolean v) { + setBool(PREF_PREFIX_FOLDER_SORT_SHOW_DOT + cleanPath(path), v); return v; } - public String getFileBrowserSortByType() { - return getString(R.string.pref_key__file_browser__sort_by_type, GsFileUtils.SORT_BY_NAME); + public boolean getFileBrowserFilterShowDotFiles(final String path) { + return getBool(PREF_PREFIX_FOLDER_SORT_SHOW_DOT + cleanPath(path), getBool(PREF_PREFIX_FOLDER_SORT_SHOW_DOT, true)); } - public boolean setFileBrowserSortReverse(boolean value) { - setBool(R.string.pref_key__sort_reverse, value); - return value; + public void clearFileBrowserFilterShowDotFiles(final String path) { + if (!GsTextUtils.isNullOrEmpty(path.trim())) { + remove(PREF_PREFIX_FOLDER_SORT_SHOW_DOT + cleanPath(path)); + } } - public boolean isFileBrowserSortReverse() { - return getBool(R.string.pref_key__sort_reverse, false); + public boolean setFileBrowserSortFolderFirst(final String path, final boolean v) { + setBool(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST + cleanPath(path), v); + return v; } - public boolean setFileBrowserFilterShowDotFiles(boolean v) { - setBool(R.string.pref_key__show_dot_files_v2, v); - return v; + public boolean getFileBrowserSortFolderFirst(final String path) { + return getBool(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST + cleanPath(path), getBool(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST, true)); } - public boolean isFileBrowserFilterShowDotFiles() { - return getBool(R.string.pref_key__show_dot_files_v2, true); + public void clearFileBrowserSortFolderFirst(final String path) { + if (!GsTextUtils.isNullOrEmpty(path.trim())) { + remove(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST + cleanPath(path)); + } } public boolean isShowSettingsOptionInMainToolbar() { @@ -788,16 +773,6 @@ public boolean isSwipeToChangeMode() { return getBool(R.string.pref_key__swipe_to_change_mode, false); } - public boolean setFileBrowserSortFolderFirst(boolean v) { - setBool(R.string.pref_key__filesystem_folder_first, v); - return v; - } - - - public boolean isFileBrowserSortFolderFirst() { - return getBool(R.string.pref_key__filesystem_folder_first, true); - } - public String getNavigationBarColor() { return getString(R.string.pref_key__navigationbar_color, "#000000"); } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java index 4eedfe4998..3eb5c29cd1 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserDialog.java @@ -311,9 +311,9 @@ public void onFsViewerItemLongPressed(File file, boolean doSelectMultiple) { } @Override - public void onFsViewerFolderChanged(File newFolder) { + public void onFsViewerFolderChange(File newFolder) { if (_callback != null) { - _callback.onFsViewerFolderChanged(newFolder); + _callback.onFsViewerFolderChange(newFolder); } } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java index 54bd18bfea..c88459e8b9 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java @@ -21,7 +21,6 @@ import android.app.Activity; import android.content.Context; import android.graphics.Color; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Pair; import android.view.Menu; @@ -90,6 +89,7 @@ public static GsFileBrowserFragment newInstance() { private GsFileBrowserOptions.SelectionListener _callback; private AppSettings _appSettings; private Menu _fragmentMenu; + private MenuItem _saveSortState; private MarkorContextUtils _cu; private Toolbar _toolbar; private boolean _reloadRequiredOnResume = true; @@ -182,29 +182,17 @@ private void checkOptions() { } @Override - public void onFsViewerFolderChanged(final File newFolder) { + public void onFsViewerFolderChange(final File newFolder) { if (_callback != null) { - _callback.onFsViewerFolderChanged(newFolder); + _callback.onFsViewerFolderChange(newFolder); } - final AppSettings.FolderSortOrder order = _appSettings.getFolderSortOrder(GsFileUtils.getPath(newFolder)); - if (order != null) { - _dopt.sortByType = order.sortByType; - _dopt.sortFolderFirst = order.folderFirst; - _dopt.sortReverse = order.reverse; - _dopt.filterShowDotFiles = order.showDotFiles; - } else { - _dopt.sortByType = _appSettings.getFileBrowserSortByType(); - _dopt.sortFolderFirst = _appSettings.isFileBrowserSortFolderFirst(); - _dopt.sortReverse = _appSettings.isFileBrowserSortReverse(); - _dopt.filterShowDotFiles = _appSettings.isFileBrowserFilterShowDotFiles(); - } - - // final MenuItem sortItem = _fragmentMenu.findItem(R.id.action_sort); - // if (sortItem != null) { - // sortItem.setChecked(order != null); - // _cu.tintDrawable(sortItem.getIcon(), order != null ? 0xFFE3B51B : Color.WHITE); - // } + final String path = getSortKey(); + _dopt.sortByType = _appSettings.getFileBrowserSortByType(path); + _dopt.sortFolderFirst = _appSettings.getFileBrowserSortFolderFirst(path); + _dopt.sortReverse = _appSettings.getFileBrowserSortReverse(path); + _dopt.filterShowDotFiles = _appSettings.getFileBrowserFilterShowDotFiles(path); + updateSortMenuStates(); } @Override @@ -254,7 +242,6 @@ public void onFsViewerDoUiUpdate(GsFileBrowserListAdapter adapter) { } private void updateMenuItems() { - final String curFilepath = (getCurrentFolder() != null ? getCurrentFolder() : new File("/")).getAbsolutePath(); final Set selFiles = _filesystemViewerAdapter.getCurrentSelection(); final int selCount = selFiles.size(); final int totalCount = _filesystemViewerAdapter.getItemCount() - 1; // Account for ".." @@ -305,6 +292,8 @@ private void updateMenuItems() { _toolbar.setSubtitle(""); } } + + updateSortMenuStates(); } @Override @@ -359,38 +348,44 @@ public void onResume() { _reloadRequiredOnResume = true; } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.filesystem__menu, menu); - _cu.tintMenuItems(menu, true, Color.WHITE); - _cu.setSubMenuIconsVisibility(menu, true); + private void updateSortMenuStates() { + if (_fragmentMenu == null) { + return; + } MenuItem item; - if ((item = menu.findItem(R.id.action_folder_first)) != null) { + if ((item = _fragmentMenu.findItem(R.id.action_folder_first)) != null) { item.setChecked(_dopt.sortFolderFirst); } - if ((item = menu.findItem(R.id.action_sort_reverse)) != null) { + if ((item = _fragmentMenu.findItem(R.id.action_sort_reverse)) != null) { item.setChecked(_dopt.sortReverse); } - if ((item = menu.findItem(R.id.action_show_dotfiles)) != null) { + if ((item = _fragmentMenu.findItem(R.id.action_show_dotfiles)) != null) { item.setChecked(_dopt.filterShowDotFiles); } - if ((item = menu.findItem(R.id.action_sort_by_name)) != null && GsFileUtils.SORT_BY_NAME.equals(_dopt.sortByType)) { + if ((item = _fragmentMenu.findItem(R.id.action_sort_by_name)) != null && GsFileUtils.SORT_BY_NAME.equals(_dopt.sortByType)) { item.setChecked(true); - } else if ((item = menu.findItem(R.id.action_sort_by_date)) != null && GsFileUtils.SORT_BY_MTIME.equals(_dopt.sortByType)) { + } else if ((item = _fragmentMenu.findItem(R.id.action_sort_by_date)) != null && GsFileUtils.SORT_BY_MTIME.equals(_dopt.sortByType)) { item.setChecked(true); - } else if ((item = menu.findItem(R.id.action_sort_by_filesize)) != null && GsFileUtils.SORT_BY_FILESIZE.equals(_dopt.sortByType)) { + } else if ((item = _fragmentMenu.findItem(R.id.action_sort_by_filesize)) != null && GsFileUtils.SORT_BY_FILESIZE.equals(_dopt.sortByType)) { item.setChecked(true); - } else if ((item = menu.findItem(R.id.action_sort_by_mimetype)) != null && GsFileUtils.SORT_BY_MIMETYPE.equals(_dopt.sortByType)) { + } else if ((item = _fragmentMenu.findItem(R.id.action_sort_by_mimetype)) != null && GsFileUtils.SORT_BY_MIMETYPE.equals(_dopt.sortByType)) { item.setChecked(true); } + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.filesystem__menu, menu); + _cu.tintMenuItems(menu, true, Color.WHITE); + _cu.setSubMenuIconsVisibility(menu, true); List> sdcardFolders = _cu.getAppDataPublicDirs(getContext(), false, true, true); int[] sdcardResIds = {}; for (int i = 0; i < sdcardResIds.length && i < sdcardFolders.size(); i++) { - item = menu.findItem(sdcardResIds[i]); + final MenuItem item = menu.findItem(sdcardResIds[i]); item.setTitle(item.getTitle().toString().replaceFirst("[)]\\s*$", " " + sdcardFolders.get(i).second) + ")"); item.setVisible(true); } @@ -403,6 +398,18 @@ public GsFileBrowserListAdapter getAdapter() { return _filesystemViewerAdapter; } + private boolean isSortSaved() { + if (_fragmentMenu != null) { + final MenuItem item = _fragmentMenu.findItem(R.id.action_save_sort_settings); + return item != null && item.isChecked(); + } + return false; + } + + private String getSortKey() { + return isSortSaved() ? GsFileUtils.getPath(getCurrentFolder()) : null; + } + @Override public boolean onOptionsItemSelected(final MenuItem item) { final int _id = item.getItemId(); @@ -416,37 +423,39 @@ public boolean onOptionsItemSelected(final MenuItem item) { } case R.id.action_sort_by_name: { item.setChecked(true); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(GsFileUtils.SORT_BY_NAME); + _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_NAME); reloadCurrentFolder(); return true; } case R.id.action_sort_by_date: { item.setChecked(true); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(GsFileUtils.SORT_BY_MTIME); + _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_MTIME); reloadCurrentFolder(); return true; } case R.id.action_sort_by_filesize: { item.setChecked(true); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(GsFileUtils.SORT_BY_FILESIZE); + final String path = GsFileUtils.getPath(getCurrentFolder()); + _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_FILESIZE); reloadCurrentFolder(); return true; } case R.id.action_sort_by_mimetype: { item.setChecked(true); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(GsFileUtils.SORT_BY_MIMETYPE); + final String path = GsFileUtils.getPath(getCurrentFolder()); + _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_MIMETYPE); reloadCurrentFolder(); return true; } case R.id.action_sort_reverse: { item.setChecked(!item.isChecked()); - _dopt.sortReverse = _appSettings.setFileBrowserSortReverse(item.isChecked()); + _dopt.sortReverse = _appSettings.setFileBrowserSortReverse(getSortKey(), item.isChecked()); reloadCurrentFolder(); return true; } case R.id.action_show_dotfiles: { item.setChecked(!item.isChecked()); - _dopt.filterShowDotFiles = _appSettings.setFileBrowserFilterShowDotFiles(item.isChecked()); + _dopt.filterShowDotFiles = _appSettings.setFileBrowserFilterShowDotFiles(getSortKey(), item.isChecked()); reloadCurrentFolder(); return true; } @@ -460,7 +469,7 @@ public boolean onOptionsItemSelected(final MenuItem item) { } case R.id.action_folder_first: { item.setChecked(!item.isChecked()); - _dopt.sortFolderFirst = _appSettings.setFileBrowserSortFolderFirst(item.isChecked()); + _dopt.sortFolderFirst = _appSettings.setFileBrowserSortFolderFirst(getSortKey(), item.isChecked()); reloadCurrentFolder(); return true; } @@ -543,17 +552,18 @@ public boolean onOptionsItemSelected(final MenuItem item) { } case R.id.action_save_sort_settings: { item.setChecked(!item.isChecked()); - final AppSettings.FolderSortOrder order; + final String path = GsFileUtils.getPath(getCurrentFolder()); if (item.isChecked()) { - order = new AppSettings.FolderSortOrder(); - order.sortByType = _dopt.sortByType; - order.folderFirst = _dopt.sortFolderFirst; - order.reverse = _dopt.sortReverse; - order.showDotFiles = _dopt.filterShowDotFiles; + _appSettings.setFileBrowserSortByType(path, _dopt.sortByType); + _appSettings.setFileBrowserSortFolderFirst(path, _dopt.sortFolderFirst); + _appSettings.setFileBrowserFilterShowDotFiles(path, _dopt.filterShowDotFiles); + _appSettings.setFileBrowserSortReverse(path, _dopt.sortReverse); } else { - order = null; + _appSettings.clearFileBrowserSortByType(path); + _appSettings.clearFileBrowserSortFolderFirst(path); + _appSettings.clearFileBrowserFilterShowDotFiles(path); + _appSettings.clearFileBrowserSortReverse(path); } - _appSettings.setFolderSortOrder(GsFileUtils.getPath(getCurrentFolder()), order); return true; } } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java index 5b8bc316e6..b723d87270 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java @@ -49,7 +49,6 @@ import java.io.FilenameFilter; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -664,7 +663,7 @@ private void loadFolder(final File folder, final File show) { } if (folderChanged) { - _dopt.listener.onFsViewerFolderChanged(_currentFolder); + _dopt.listener.onFsViewerFolderChange(_currentFolder); } if (_currentFolder != null) { diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java index 71b9e5ab9a..3e7eb15aec 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java @@ -42,7 +42,7 @@ public interface SelectionListener { void onFsViewerItemLongPressed(final File file, boolean doSelectMultiple); - void onFsViewerFolderChanged(final File newFolder); + void onFsViewerFolderChange(final File newFolder); } public static class Options { @@ -170,7 +170,7 @@ public void onFsViewerItemLongPressed(File file, boolean doSelectMultiple) { } @Override - public void onFsViewerFolderChanged(File newFolder) { + public void onFsViewerFolderChange(File newFolder) { } } diff --git a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java index 0efd19620f..31636f8446 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java @@ -74,16 +74,6 @@ public class GsFileUtils { private final static int BUFFER_SIZE = 4096; private final static Map MIME_TYPE_CACHE = new ConcurrentHashMap<>(); - public static String getPath(final File file) { - try { - return file.getCanonicalPath(); - } catch (IOException e) { - return file.getAbsolutePath(); - } catch (NullPointerException e) { - return ""; - } - } - /** * Info of various types about a file */ @@ -939,4 +929,14 @@ public FileVisitResult visitFile(final Path path, final BasicFileAttributes attr } return null; } + + public static String getPath(final File file) { + try { + return file.getCanonicalPath(); + } catch (IOException e) { + return file.getAbsolutePath(); + } catch (NullPointerException e) { + return ""; + } + } } diff --git a/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java b/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java index 69af563f14..a6ca50cf12 100644 --- a/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java +++ b/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java @@ -52,6 +52,7 @@ public void onDataSetChanged() { final File dir = WrWidgetConfigure.getWidgetDirectory(_context, _appWidgetId); final AppSettings as = ApplicationObject.settings(); + final String path = GsFileUtils.getPath(dir); if (dir.equals(GsFileBrowserListAdapter.VIRTUAL_STORAGE_RECENTS)) { _widgetFilesList.addAll(ApplicationObject.settings().getRecentFiles()); } else if (dir.equals(GsFileBrowserListAdapter.VIRTUAL_STORAGE_POPULAR)) { @@ -59,11 +60,17 @@ public void onDataSetChanged() { } else if (dir.equals(GsFileBrowserListAdapter.VIRTUAL_STORAGE_FAVOURITE)) { _widgetFilesList.addAll(ApplicationObject.settings().getFavouriteFiles()); } else if (dir.exists() && dir.canRead()) { - final boolean showDot = as.isFileBrowserFilterShowDotFiles(); + final boolean showDot = as.getFileBrowserFilterShowDotFiles(path); final File[] all = dir.listFiles(file -> showDot || !file.getName().startsWith(".")); _widgetFilesList.addAll(all != null ? Arrays.asList(all) : Collections.emptyList()); } - GsFileUtils.sortFiles(_widgetFilesList, as.getFileBrowserSortByType(), as.isFileBrowserSortFolderFirst(), as.isFileBrowserSortReverse()); + + GsFileUtils.sortFiles( + _widgetFilesList, + as.getFileBrowserSortByType(path), + as.getFileBrowserSortFolderFirst(path), + as.getFileBrowserSortReverse(path) + ); } @Override From 6f79ce0db7f54dd1bda716b6a880925c17ae93a0 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Sat, 4 Jan 2025 08:22:10 -0800 Subject: [PATCH 03/12] Switching to dialog --- .../markor/activity/MainActivity.java | 2 - .../markor/frontend/MarkorDialogFactory.java | 54 ++++++++ .../filebrowser/MarkorFileBrowserFactory.java | 8 +- .../gsantner/markor/model/AppSettings.java | 117 ++++++++++------ .../frontend/GsSearchOrCustomTextDialog.java | 14 +- .../filebrowser/GsFileBrowserFragment.java | 127 +++++++++--------- .../filebrowser/GsFileBrowserListAdapter.java | 13 +- .../writeily/widget/WrFilesWidgetFactory.java | 12 +- 8 files changed, 223 insertions(+), 124 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/activity/MainActivity.java b/app/src/main/java/net/gsantner/markor/activity/MainActivity.java index d447247260..3a887b78f5 100644 --- a/app/src/main/java/net/gsantner/markor/activity/MainActivity.java +++ b/app/src/main/java/net/gsantner/markor/activity/MainActivity.java @@ -77,7 +77,6 @@ protected void onCreate(final Bundle savedInstanceState) { } catch (Exception ignored) { } - _cu = new MarkorContextUtils(this); setContentView(R.layout.main__activity); _bottomNav = findViewById(R.id.bottom_navigation_bar); @@ -427,7 +426,6 @@ public void onFsViewerDoUiUpdate(final GsFileBrowserListAdapter adapter) { if (getCurrentPos() == tabIdToPos(R.id.nav_notebook)) { setTitle(getFileBrowserTitle()); } - invalidateOptionsMenu(); } if (toShow != null && adapter != null) { diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java index f99bac19df..60b27620bc 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java @@ -998,6 +998,60 @@ public static void showInsertSnippetDialog(final Activity activity, final GsCall GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt); } + public static void showFolderSortDialog( + final Activity activity, + final String sortType, + final boolean isReverse, + final boolean isFoldersFirst, + final boolean isDotFiles, + final boolean isSaved, + final GsCallback.a5 callback + ) { + final DialogOptions dopt = new DialogOptions(); + baseConf(activity, dopt); + + final List data = new ArrayList<>(); + data.add(activity.getString(R.string.save)); + data.add(activity.getString(R.string.name)); + data.add(activity.getString(R.string.date)); + data.add(activity.getString(R.string.size)); + data.add(activity.getString(R.string.mime_type)); + data.add(activity.getString(R.string.folder_first)); + data.add(activity.getString(R.string.reverse_order)); + data.add(activity.getString(R.string.dotfiles)); + dopt.data = data; + + dopt.preSelected = new HashSet<>(); + if (isReverse) dopt.preSelected.add(6); + if (isFoldersFirst) dopt.preSelected.add(5); + if (isDotFiles) dopt.preSelected.add(7); + if (isSaved) dopt.preSelected.add(0); + if (GsFileUtils.SORT_BY_NAME.equals(sortType)) dopt.preSelected.add(1); + else if (GsFileUtils.SORT_BY_MTIME.equals(sortType)) dopt.preSelected.add(2); + else if (GsFileUtils.SORT_BY_FILESIZE.equals(sortType)) dopt.preSelected.add(3); + else if (GsFileUtils.SORT_BY_MIMETYPE.equals(sortType)) dopt.preSelected.add(4); + + dopt.radioSet = new HashSet<>(Arrays.asList(1, 2, 3, 4)); + dopt.isMultiSelectEnabled = true; + dopt.isSearchEnabled = false; + dopt.titleText = R.string.sort_by; + + dopt.positionCallback = (selection) -> { + final boolean reverse = selection.contains(6); + final boolean foldersFirst = selection.contains(5); + final boolean dotFiles = selection.contains(7); + final String sortBy; + if (selection.contains(2)) sortBy = GsFileUtils.SORT_BY_MTIME; + else if (selection.contains(3)) sortBy = GsFileUtils.SORT_BY_FILESIZE; + else if (selection.contains(4)) sortBy = GsFileUtils.SORT_BY_MIMETYPE; + else sortBy = GsFileUtils.SORT_BY_NAME; + final boolean save = selection.contains(0); + callback.callback(sortBy, reverse, foldersFirst, dotFiles, save); + }; + + GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt); + } + public static void baseConf(Activity activity, DialogOptions dopt) { dopt.isDarkDialog = GsContextUtils.instance.isDarkModeEnabled(activity); dopt.clearInputIcon = R.drawable.ic_baseline_clear_24; diff --git a/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java b/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java index 89994a8975..1572157712 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java @@ -85,10 +85,10 @@ public static void updateFsViewerOpts( ) { appSettings = appSettings != null ? appSettings : ApplicationObject.settings(); - opts.sortFolderFirst = appSettings.getFileBrowserSortFolderFirst(null); - opts.sortByType = appSettings.getFileBrowserSortByType(null); - opts.sortReverse = appSettings.getFileBrowserSortReverse(null); - opts.filterShowDotFiles = appSettings.getFileBrowserFilterShowDotFiles(null); + 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(); diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index d726d39f1d..5a5090be47 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -45,6 +45,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -260,73 +261,93 @@ public boolean isRecreateMainRequired() { return ret; } - private final String PREF_PREFIX_FOLDER_SORT_TYPE = "PREF_PREFIX_FOLDER_SORT_TYPE"; - private final String PREF_PREFIX_FOLDER_SORT_REVERSE = "PREF_PREFIX_FOLDER_SORT_REVERSE"; - private final String PREF_PREFIX_FOLDER_SORT_SHOW_DOT = "PREF_PREFIX_FOLDER_SORT_SHOW_DOT"; - private final String PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST = "PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST"; + private final String PREF_PREFIX_FOLDER_SORT_ORDER = "PREF_PREFIX_FOLDER_SORT_ORDER"; - private String cleanPath(final String path) { - return GsTextUtils.isNullOrEmpty(path) ? "" : path.trim(); - } + public static class FolderSortOrder { + private final static String SORT_BY_KEY = "SORT_BY"; + private final static String REVERSE_KEY = "REVERSE"; + private final static String SHOW_DOT_FILES_KEY = "SHOW_DOT_FILES"; + private final static String FOLDER_FIRST_KEY = "FOLDER_FIRST"; - public String setFileBrowserSortByType(final String path, final String type) { - setString(PREF_PREFIX_FOLDER_SORT_TYPE + cleanPath(path), type); - return type; + public String sortByType = GsFileUtils.SORT_BY_NAME; + public boolean reverse = false; + public boolean showDotFiles = false; + public boolean folderFirst = true; + public boolean hasCustomOrder = false; } - public String getFileBrowserSortByType(final String path) { - return getString(PREF_PREFIX_FOLDER_SORT_TYPE + cleanPath(path), getString(PREF_PREFIX_FOLDER_SORT_TYPE, GsFileUtils.SORT_BY_NAME)); - } + public void setFolderSortOrder(final File folder, final @Nullable FolderSortOrder sortOrder) { + final String canonicalPath = GsFileUtils.getPath(folder); - public void clearFileBrowserSortByType(final String path) { - if (!GsTextUtils.isNullOrEmpty(path.trim())) { - remove(PREF_PREFIX_FOLDER_SORT_TYPE + cleanPath(path)); + if (TextUtils.isEmpty(canonicalPath)) { + return; } - } - public boolean setFileBrowserSortReverse(final String path, final boolean value) { - setBool(PREF_PREFIX_FOLDER_SORT_REVERSE + cleanPath(path), value); - return value; - } + final String key = PREF_PREFIX_FOLDER_SORT_ORDER + canonicalPath; - public boolean getFileBrowserSortReverse(final String path) { - return getBool(PREF_PREFIX_FOLDER_SORT_REVERSE + cleanPath(path), getBool(PREF_PREFIX_FOLDER_SORT_REVERSE, false)); + if (sortOrder == null) { + remove(key); + return; + } + + final Map order = new HashMap<>(); + order.put(FolderSortOrder.SORT_BY_KEY, sortOrder.sortByType != null ? sortOrder.sortByType : GsFileUtils.SORT_BY_NAME); + order.put(FolderSortOrder.REVERSE_KEY, String.valueOf(sortOrder.reverse)); + order.put(FolderSortOrder.SHOW_DOT_FILES_KEY, String.valueOf(sortOrder.showDotFiles)); + order.put(FolderSortOrder.FOLDER_FIRST_KEY, String.valueOf(sortOrder.folderFirst)); + + setString(key, mapToJsonString(order)); } - public void clearFileBrowserSortReverse(final String path) { - if (!GsTextUtils.isNullOrEmpty(path.trim())) { - remove(PREF_PREFIX_FOLDER_SORT_REVERSE + cleanPath(path)); + public FolderSortOrder getFolderSortOrder(final File folder) { + final String path = GsFileUtils.getPath(folder); + final String key = PREF_PREFIX_FOLDER_SORT_ORDER + path; + final String json = getString(key, null); + + final FolderSortOrder sortOrder = new FolderSortOrder(); + if (GsTextUtils.isNullOrEmpty(path) || json == null) { + sortOrder.sortByType = getFileBrowserSortByType(); + sortOrder.reverse = isFileBrowserSortReverse(); + sortOrder.folderFirst = isFileBrowserSortFolderFirst(); + sortOrder.showDotFiles = isFileBrowserFilterShowDotFiles(); + sortOrder.hasCustomOrder = false; + } else { + final Map order = jsonStringToMap(getString(key, "{}")); + sortOrder.sortByType = order.get(FolderSortOrder.SORT_BY_KEY); + sortOrder.reverse = Boolean.parseBoolean(order.get(FolderSortOrder.REVERSE_KEY)); + sortOrder.showDotFiles = Boolean.parseBoolean(order.get(FolderSortOrder.SHOW_DOT_FILES_KEY)); + sortOrder.folderFirst = Boolean.parseBoolean(order.get(FolderSortOrder.FOLDER_FIRST_KEY)); + sortOrder.hasCustomOrder = true; } + + return sortOrder; } - public boolean setFileBrowserFilterShowDotFiles(final String path, final boolean v) { - setBool(PREF_PREFIX_FOLDER_SORT_SHOW_DOT + cleanPath(path), v); + public String setFileBrowserSortByType(String v) { + setString(R.string.pref_key__file_browser__sort_by_type, v); return v; } - public boolean getFileBrowserFilterShowDotFiles(final String path) { - return getBool(PREF_PREFIX_FOLDER_SORT_SHOW_DOT + cleanPath(path), getBool(PREF_PREFIX_FOLDER_SORT_SHOW_DOT, true)); + public String getFileBrowserSortByType() { + return getString(R.string.pref_key__file_browser__sort_by_type, GsFileUtils.SORT_BY_NAME); } - public void clearFileBrowserFilterShowDotFiles(final String path) { - if (!GsTextUtils.isNullOrEmpty(path.trim())) { - remove(PREF_PREFIX_FOLDER_SORT_SHOW_DOT + cleanPath(path)); - } + public boolean setFileBrowserSortReverse(boolean value) { + setBool(R.string.pref_key__sort_reverse, value); + return value; } - public boolean setFileBrowserSortFolderFirst(final String path, final boolean v) { - setBool(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST + cleanPath(path), v); - return v; + public boolean isFileBrowserSortReverse() { + return getBool(R.string.pref_key__sort_reverse, false); } - public boolean getFileBrowserSortFolderFirst(final String path) { - return getBool(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST + cleanPath(path), getBool(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST, true)); + public boolean setFileBrowserFilterShowDotFiles(boolean v) { + setBool(R.string.pref_key__show_dot_files_v2, v); + return v; } - public void clearFileBrowserSortFolderFirst(final String path) { - if (!GsTextUtils.isNullOrEmpty(path.trim())) { - remove(PREF_PREFIX_FOLDER_SORT_FOLDER_FIRST + cleanPath(path)); - } + public boolean isFileBrowserFilterShowDotFiles() { + return getBool(R.string.pref_key__show_dot_files_v2, true); } public boolean isShowSettingsOptionInMainToolbar() { @@ -773,6 +794,16 @@ public boolean isSwipeToChangeMode() { return getBool(R.string.pref_key__swipe_to_change_mode, false); } + public boolean setFileBrowserSortFolderFirst(boolean v) { + setBool(R.string.pref_key__filesystem_folder_first, v); + return v; + } + + + public boolean isFileBrowserSortFolderFirst() { + return getBool(R.string.pref_key__filesystem_folder_first, true); + } + public String getNavigationBarColor() { return getString(R.string.pref_key__navigationbar_color, "#000000"); } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java index 1929df7dbf..d5cbf3b1cc 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java @@ -88,6 +88,7 @@ public static class DialogOptions { public List data = null; public List highlightData = null; public List iconsForData; + public Collection radioSet = null; public CharSequence messageText = ""; public String defaultText = ""; public boolean isDarkDialog = false; @@ -450,10 +451,15 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi listAdapter._selectedItems.remove(index); } else { listAdapter._selectedItems.add(index); + if (dopt.radioSet != null && dopt.radioSet.contains(index)) { + for (int i : dopt.radioSet) { + if (i != index) { + listAdapter._selectedItems.remove(i); + } + } + } } - if (textView instanceof Checkable) { - ((Checkable) textView).setChecked(listAdapter._selectedItems.contains(index)); - } + listAdapter.notifyDataSetChanged(); setOkButtonState.callback(); setSelectAllButtonState.callback(); } else { @@ -512,7 +518,7 @@ private static View makeTitleView(final Context context, final DialogOptions dop LinearLayout.LayoutParams.WRAP_CONTENT)); } - if (dopt.isMultiSelectEnabled) { + if (dopt.isMultiSelectEnabled && dopt.radioSet != null) { // Using a multiple choice text view as a selectable checkbox button // Requires no styling to match the existing check boxes final LayoutInflater inflater = LayoutInflater.from(context); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java index c88459e8b9..aba04150d9 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java @@ -89,10 +89,10 @@ public static GsFileBrowserFragment newInstance() { private GsFileBrowserOptions.SelectionListener _callback; private AppSettings _appSettings; private Menu _fragmentMenu; - private MenuItem _saveSortState; private MarkorContextUtils _cu; private Toolbar _toolbar; private boolean _reloadRequiredOnResume = true; + private boolean _isSortOrderSaved = false; //######################## //## Methods @@ -126,7 +126,6 @@ public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceStat _filesystemViewerAdapter = new GsFileBrowserListAdapter(_dopt, context); _recyclerList.setAdapter(_filesystemViewerAdapter); setReloadRequiredOnResume(false); // setAdapter will trigger a load - onFsViewerDoUiUpdate(_filesystemViewerAdapter); _swipe.setOnRefreshListener(() -> { _filesystemViewerAdapter.reloadCurrentFolder(); @@ -187,12 +186,12 @@ public void onFsViewerFolderChange(final File newFolder) { _callback.onFsViewerFolderChange(newFolder); } - final String path = getSortKey(); - _dopt.sortByType = _appSettings.getFileBrowserSortByType(path); - _dopt.sortFolderFirst = _appSettings.getFileBrowserSortFolderFirst(path); - _dopt.sortReverse = _appSettings.getFileBrowserSortReverse(path); - _dopt.filterShowDotFiles = _appSettings.getFileBrowserFilterShowDotFiles(path); - updateSortMenuStates(); + final AppSettings.FolderSortOrder order = _appSettings.getFolderSortOrder(newFolder); + _dopt.sortByType = order.sortByType; + _dopt.sortFolderFirst = order.folderFirst; + _dopt.sortReverse = order.reverse; + _dopt.filterShowDotFiles = order.showDotFiles; + _isSortOrderSaved = order.hasCustomOrder; } @Override @@ -237,8 +236,7 @@ public void onFsViewerDoUiUpdate(GsFileBrowserListAdapter adapter) { } updateMenuItems(); - _emptyHint.postDelayed(() -> _emptyHint.setVisibility(adapter.isCurrentFolderEmpty() ? View.VISIBLE : View.GONE), 200); - _recyclerList.postDelayed(this::updateMenuItems, 1000); + _emptyHint.setVisibility(adapter.isCurrentFolderEmpty() ? View.VISIBLE : View.GONE); } private void updateMenuItems() { @@ -273,7 +271,7 @@ private void updateMenuItems() { _fragmentMenu.findItem(R.id.action_copy_selected_items).setVisible((selMulti1 || selMultiMore) && selWritable && !_cu.isUnderStorageAccessFolder(getContext(), getCurrentFolder(), true)); _fragmentMenu.findItem(R.id.action_share_files).setVisible(selFilesOnly && (selMulti1 || selMultiMore) && !_cu.isUnderStorageAccessFolder(getContext(), getCurrentFolder(), true)); _fragmentMenu.findItem(R.id.action_go_to).setVisible(!_filesystemViewerAdapter.areItemsSelected()); - _fragmentMenu.findItem(R.id.action_sort).setVisible(!_filesystemViewerAdapter.areItemsSelected()); + _fragmentMenu.findItem(R.id.action_sort).setVisible(_filesystemViewerAdapter.isCurrentFolderSortable() && !_filesystemViewerAdapter.areItemsSelected()); _fragmentMenu.findItem(R.id.action_import).setVisible(!_filesystemViewerAdapter.areItemsSelected() && !_filesystemViewerAdapter.isCurrentFolderVirtual()); _fragmentMenu.findItem(R.id.action_settings).setVisible(!_filesystemViewerAdapter.areItemsSelected()); _fragmentMenu.findItem(R.id.action_favourite).setVisible(selMultiAny && !allSelectedFav); @@ -313,7 +311,6 @@ public boolean onBackPressed() { public void reloadCurrentFolder() { _filesystemViewerAdapter.reloadCurrentFolder(); - onFsViewerDoUiUpdate(_filesystemViewerAdapter); } public File getCurrentFolder() { @@ -363,6 +360,12 @@ private void updateSortMenuStates() { if ((item = _fragmentMenu.findItem(R.id.action_show_dotfiles)) != null) { item.setChecked(_dopt.filterShowDotFiles); } + if ((item = _fragmentMenu.findItem(R.id.action_save_sort_settings)) != null) { + item.setChecked(_isSortOrderSaved); + } + if ((item = _fragmentMenu.findItem(R.id.action_sort)) != null) { + _cu.tintDrawable(item.getIcon(), _isSortOrderSaved ? GsFileBrowserListAdapter.FAVOURITE_COLOR : Color.WHITE); + } if ((item = _fragmentMenu.findItem(R.id.action_sort_by_name)) != null && GsFileUtils.SORT_BY_NAME.equals(_dopt.sortByType)) { item.setChecked(true); @@ -398,16 +401,22 @@ public GsFileBrowserListAdapter getAdapter() { return _filesystemViewerAdapter; } - private boolean isSortSaved() { - if (_fragmentMenu != null) { - final MenuItem item = _fragmentMenu.findItem(R.id.action_save_sort_settings); - return item != null && item.isChecked(); + private void updateSortSettingsAndReload() { + if (_isSortOrderSaved) { + final AppSettings.FolderSortOrder order = new AppSettings.FolderSortOrder(); + order.sortByType = _dopt.sortByType; + order.reverse = _dopt.sortReverse; + order.folderFirst = _dopt.sortFolderFirst; + order.showDotFiles = _dopt.filterShowDotFiles; + _appSettings.setFolderSortOrder(getCurrentFolder(), order); + } else { + _appSettings.setFolderSortOrder(getCurrentFolder(), null); + _appSettings.setFileBrowserSortByType(_dopt.sortByType); + _appSettings.setFileBrowserSortReverse(_dopt.sortReverse); + _appSettings.setFileBrowserSortFolderFirst(_dopt.sortFolderFirst); + _appSettings.setFileBrowserFilterShowDotFiles(_dopt.filterShowDotFiles); } - return false; - } - - private String getSortKey() { - return isSortSaved() ? GsFileUtils.getPath(getCurrentFolder()) : null; + reloadCurrentFolder(); // onFsViewerFolderChange will update the UI } @Override @@ -422,41 +431,38 @@ public boolean onOptionsItemSelected(final MenuItem item) { return true; } case R.id.action_sort_by_name: { - item.setChecked(true); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_NAME); - reloadCurrentFolder(); + _dopt.sortByType = GsFileUtils.SORT_BY_NAME; + updateSortSettingsAndReload(); return true; } case R.id.action_sort_by_date: { - item.setChecked(true); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_MTIME); - reloadCurrentFolder(); + _dopt.sortByType = GsFileUtils.SORT_BY_MTIME; + updateSortSettingsAndReload(); return true; } case R.id.action_sort_by_filesize: { - item.setChecked(true); - final String path = GsFileUtils.getPath(getCurrentFolder()); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_FILESIZE); - reloadCurrentFolder(); + _dopt.sortByType = GsFileUtils.SORT_BY_FILESIZE; + updateSortSettingsAndReload(); return true; } case R.id.action_sort_by_mimetype: { - item.setChecked(true); - final String path = GsFileUtils.getPath(getCurrentFolder()); - _dopt.sortByType = _appSettings.setFileBrowserSortByType(getSortKey(), GsFileUtils.SORT_BY_MIMETYPE); - reloadCurrentFolder(); + _dopt.sortByType = GsFileUtils.SORT_BY_MIMETYPE; + updateSortSettingsAndReload(); return true; } case R.id.action_sort_reverse: { - item.setChecked(!item.isChecked()); - _dopt.sortReverse = _appSettings.setFileBrowserSortReverse(getSortKey(), item.isChecked()); - reloadCurrentFolder(); + _dopt.sortReverse = !_dopt.sortReverse; + updateSortSettingsAndReload(); return true; } case R.id.action_show_dotfiles: { - item.setChecked(!item.isChecked()); - _dopt.filterShowDotFiles = _appSettings.setFileBrowserFilterShowDotFiles(getSortKey(), item.isChecked()); - reloadCurrentFolder(); + _dopt.filterShowDotFiles = !_dopt.filterShowDotFiles; + updateSortSettingsAndReload(); + return true; + } + case R.id.action_folder_first: { + _dopt.sortFolderFirst = !_dopt.sortFolderFirst; + updateSortSettingsAndReload(); return true; } case R.id.action_import: { @@ -467,12 +473,6 @@ public boolean onOptionsItemSelected(final MenuItem item) { executeSearchAction(); return true; } - case R.id.action_folder_first: { - item.setChecked(!item.isChecked()); - _dopt.sortFolderFirst = _appSettings.setFileBrowserSortFolderFirst(getSortKey(), item.isChecked()); - reloadCurrentFolder(); - return true; - } case R.id.action_go_to: { final File folder = new File("/storage"); _filesystemViewerAdapter.setCurrentFolder(folder); @@ -551,19 +551,8 @@ public boolean onOptionsItemSelected(final MenuItem item) { return true; } case R.id.action_save_sort_settings: { - item.setChecked(!item.isChecked()); - final String path = GsFileUtils.getPath(getCurrentFolder()); - if (item.isChecked()) { - _appSettings.setFileBrowserSortByType(path, _dopt.sortByType); - _appSettings.setFileBrowserSortFolderFirst(path, _dopt.sortFolderFirst); - _appSettings.setFileBrowserFilterShowDotFiles(path, _dopt.filterShowDotFiles); - _appSettings.setFileBrowserSortReverse(path, _dopt.sortReverse); - } else { - _appSettings.clearFileBrowserSortByType(path); - _appSettings.clearFileBrowserSortFolderFirst(path); - _appSettings.clearFileBrowserFilterShowDotFiles(path); - _appSettings.clearFileBrowserSortReverse(path); - } + _isSortOrderSaved = !_isSortOrderSaved; + updateSortSettingsAndReload(); return true; } } @@ -691,4 +680,22 @@ private void importFileToCurrentDirectory(Context context, File sourceFile) { public GsFileBrowserOptions.Options getOptions() { return _dopt; } + + private void updateSortSettings() { + MarkorDialogFactory.showFolderSortDialog( + getActivity(), + _dopt.sortByType, + _dopt.sortReverse, + _dopt.sortFolderFirst, + _dopt.filterShowDotFiles, + _isSortOrderSaved, + (sortByType, sortReverse, sortFolderFirst, filterShowDotFiles, saved) -> { + _dopt.sortByType = sortByType; + _dopt.sortReverse = sortReverse; + _dopt.sortFolderFirst = sortFolderFirst; + _dopt.filterShowDotFiles = filterShowDotFiles; + _isSortOrderSaved = saved; + updateSortSettingsAndReload(); + }); + } } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java index b723d87270..4228335e37 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java @@ -49,6 +49,7 @@ import java.io.FilenameFilter; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -78,6 +79,7 @@ public class GsFileBrowserListAdapter extends RecyclerView.Adapter s + f.lastModified(), 0L); @@ -892,4 +897,8 @@ private int getUserId() { return 0; } } + + public boolean isCurrentFolderSortable() { + return _currentFolder != null && !VIRTUAL_STORAGE_ROOT.equals(_currentFolder) && !VIRTUAL_STORAGE_RECENTS.equals(_currentFolder); + } } diff --git a/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java b/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java index a6ca50cf12..648fadd9f6 100644 --- a/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java +++ b/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java @@ -51,8 +51,8 @@ public void onDataSetChanged() { _widgetFilesList.clear(); final File dir = WrWidgetConfigure.getWidgetDirectory(_context, _appWidgetId); final AppSettings as = ApplicationObject.settings(); + final AppSettings.FolderSortOrder order = as.getFolderSortOrder(dir); - final String path = GsFileUtils.getPath(dir); if (dir.equals(GsFileBrowserListAdapter.VIRTUAL_STORAGE_RECENTS)) { _widgetFilesList.addAll(ApplicationObject.settings().getRecentFiles()); } else if (dir.equals(GsFileBrowserListAdapter.VIRTUAL_STORAGE_POPULAR)) { @@ -60,17 +60,11 @@ public void onDataSetChanged() { } else if (dir.equals(GsFileBrowserListAdapter.VIRTUAL_STORAGE_FAVOURITE)) { _widgetFilesList.addAll(ApplicationObject.settings().getFavouriteFiles()); } else if (dir.exists() && dir.canRead()) { - final boolean showDot = as.getFileBrowserFilterShowDotFiles(path); - final File[] all = dir.listFiles(file -> showDot || !file.getName().startsWith(".")); + final File[] all = dir.listFiles(file -> order.showDotFiles || !file.getName().startsWith(".")); _widgetFilesList.addAll(all != null ? Arrays.asList(all) : Collections.emptyList()); } - GsFileUtils.sortFiles( - _widgetFilesList, - as.getFileBrowserSortByType(path), - as.getFileBrowserSortFolderFirst(path), - as.getFileBrowserSortReverse(path) - ); + GsFileUtils.sortFiles(_widgetFilesList, order.sortByType, order.folderFirst, order.reverse); } @Override From 20b7c5e1d58e457472a398db4db04d50036bb166 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Sat, 4 Jan 2025 09:08:31 -0800 Subject: [PATCH 04/12] Switching to dialog based sort --- .../markor/frontend/MarkorDialogFactory.java | 1 + .../frontend/GsSearchOrCustomTextDialog.java | 19 ++- .../filebrowser/GsFileBrowserFragment.java | 114 ++++-------------- app/src/main/res/menu/filesystem__menu.xml | 59 +-------- 4 files changed, 38 insertions(+), 155 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java index 60b27620bc..0babd42fb1 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java @@ -1035,6 +1035,7 @@ public static void showFolderSortDialog( dopt.isMultiSelectEnabled = true; dopt.isSearchEnabled = false; dopt.titleText = R.string.sort_by; + dopt.dialogWidthDp = WindowManager.LayoutParams.WRAP_CONTENT; dopt.positionCallback = (selection) -> { final boolean reverse = selection.contains(6); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java index d5cbf3b1cc..6bb0573cdd 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java @@ -136,8 +136,6 @@ public static class DialogState { } public static class Adapter extends BaseAdapter { - @LayoutRes - private final int _layout; private final int _layoutHeight; private final LayoutInflater _inflater; private final DialogOptions _dopt; @@ -165,7 +163,6 @@ public long getItemId(int position) { private Adapter(final Context context, final DialogOptions dopt) { super(); _filteredItems = new ArrayList<>(); - _layout = dopt.isMultiSelectEnabled ? android.R.layout.simple_list_item_multiple_choice : android.R.layout.simple_list_item_1; _inflater = LayoutInflater.from(context); _dopt = dopt; _extraPattern = (_dopt.extraFilter == null ? null : Pattern.compile(_dopt.extraFilter).matcher("")); @@ -173,6 +170,18 @@ private Adapter(final Context context, final DialogOptions dopt) { _layoutHeight = GsContextUtils.instance.convertDpToPx(context, 36); } + private int chooseLayout(final int pos) { + if (_dopt.isMultiSelectEnabled) { + if (_dopt.radioSet != null && _dopt.radioSet.contains(pos)) { + return android.R.layout.simple_list_item_single_choice; + } else { + return android.R.layout.simple_list_item_multiple_choice; + } + } else { + return android.R.layout.simple_list_item_1; + } + } + @NonNull @Override public View getView(int pos, @Nullable View convertView, @NonNull ViewGroup parent) { @@ -180,7 +189,7 @@ public View getView(int pos, @Nullable View convertView, @NonNull ViewGroup pare final TextView textView; if (convertView == null) { - textView = (TextView) _inflater.inflate(_layout, parent, false); + textView = (TextView) _inflater.inflate(chooseLayout(pos), parent, false); textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); textView.setMinHeight(_layoutHeight); } else { @@ -518,7 +527,7 @@ private static View makeTitleView(final Context context, final DialogOptions dop LinearLayout.LayoutParams.WRAP_CONTENT)); } - if (dopt.isMultiSelectEnabled && dopt.radioSet != null) { + if (dopt.isMultiSelectEnabled && dopt.radioSet == null) { // Using a multiple choice text view as a selectable checkbox button // Requires no styling to match the existing check boxes final LayoutInflater inflater = LayoutInflater.from(context); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java index aba04150d9..5e980084cd 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java @@ -280,6 +280,11 @@ private void updateMenuItems() { _fragmentMenu.findItem(R.id.action_create_shortcut).setVisible(selMulti1 && (selFilesOnly || selDirectoriesOnly)); _fragmentMenu.findItem(R.id.action_check_all).setVisible(_filesystemViewerAdapter.areItemsSelected() && selCount < totalCount); _fragmentMenu.findItem(R.id.action_clear_selection).setVisible(_filesystemViewerAdapter.areItemsSelected()); + + final MenuItem sortItem = _fragmentMenu.findItem(R.id.action_sort); + if (sortItem != null) { + _cu.tintDrawable(sortItem.getIcon(), _isSortOrderSaved ? GsFileBrowserListAdapter.FAVOURITE_COLOR : Color.WHITE); + } } // Update subtitle with count @@ -290,8 +295,6 @@ private void updateMenuItems() { _toolbar.setSubtitle(""); } } - - updateSortMenuStates(); } @Override @@ -345,39 +348,6 @@ public void onResume() { _reloadRequiredOnResume = true; } - private void updateSortMenuStates() { - if (_fragmentMenu == null) { - return; - } - - MenuItem item; - if ((item = _fragmentMenu.findItem(R.id.action_folder_first)) != null) { - item.setChecked(_dopt.sortFolderFirst); - } - if ((item = _fragmentMenu.findItem(R.id.action_sort_reverse)) != null) { - item.setChecked(_dopt.sortReverse); - } - if ((item = _fragmentMenu.findItem(R.id.action_show_dotfiles)) != null) { - item.setChecked(_dopt.filterShowDotFiles); - } - if ((item = _fragmentMenu.findItem(R.id.action_save_sort_settings)) != null) { - item.setChecked(_isSortOrderSaved); - } - if ((item = _fragmentMenu.findItem(R.id.action_sort)) != null) { - _cu.tintDrawable(item.getIcon(), _isSortOrderSaved ? GsFileBrowserListAdapter.FAVOURITE_COLOR : Color.WHITE); - } - - if ((item = _fragmentMenu.findItem(R.id.action_sort_by_name)) != null && GsFileUtils.SORT_BY_NAME.equals(_dopt.sortByType)) { - item.setChecked(true); - } else if ((item = _fragmentMenu.findItem(R.id.action_sort_by_date)) != null && GsFileUtils.SORT_BY_MTIME.equals(_dopt.sortByType)) { - item.setChecked(true); - } else if ((item = _fragmentMenu.findItem(R.id.action_sort_by_filesize)) != null && GsFileUtils.SORT_BY_FILESIZE.equals(_dopt.sortByType)) { - item.setChecked(true); - } else if ((item = _fragmentMenu.findItem(R.id.action_sort_by_mimetype)) != null && GsFileUtils.SORT_BY_MIMETYPE.equals(_dopt.sortByType)) { - item.setChecked(true); - } - } - @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); @@ -401,24 +371,6 @@ public GsFileBrowserListAdapter getAdapter() { return _filesystemViewerAdapter; } - private void updateSortSettingsAndReload() { - if (_isSortOrderSaved) { - final AppSettings.FolderSortOrder order = new AppSettings.FolderSortOrder(); - order.sortByType = _dopt.sortByType; - order.reverse = _dopt.sortReverse; - order.folderFirst = _dopt.sortFolderFirst; - order.showDotFiles = _dopt.filterShowDotFiles; - _appSettings.setFolderSortOrder(getCurrentFolder(), order); - } else { - _appSettings.setFolderSortOrder(getCurrentFolder(), null); - _appSettings.setFileBrowserSortByType(_dopt.sortByType); - _appSettings.setFileBrowserSortReverse(_dopt.sortReverse); - _appSettings.setFileBrowserSortFolderFirst(_dopt.sortFolderFirst); - _appSettings.setFileBrowserFilterShowDotFiles(_dopt.filterShowDotFiles); - } - reloadCurrentFolder(); // onFsViewerFolderChange will update the UI - } - @Override public boolean onOptionsItemSelected(final MenuItem item) { final int _id = item.getItemId(); @@ -430,39 +382,8 @@ public boolean onOptionsItemSelected(final MenuItem item) { _cu.createLauncherDesktopShortcut(getContext(), file); return true; } - case R.id.action_sort_by_name: { - _dopt.sortByType = GsFileUtils.SORT_BY_NAME; - updateSortSettingsAndReload(); - return true; - } - case R.id.action_sort_by_date: { - _dopt.sortByType = GsFileUtils.SORT_BY_MTIME; - updateSortSettingsAndReload(); - return true; - } - case R.id.action_sort_by_filesize: { - _dopt.sortByType = GsFileUtils.SORT_BY_FILESIZE; - updateSortSettingsAndReload(); - return true; - } - case R.id.action_sort_by_mimetype: { - _dopt.sortByType = GsFileUtils.SORT_BY_MIMETYPE; - updateSortSettingsAndReload(); - return true; - } - case R.id.action_sort_reverse: { - _dopt.sortReverse = !_dopt.sortReverse; - updateSortSettingsAndReload(); - return true; - } - case R.id.action_show_dotfiles: { - _dopt.filterShowDotFiles = !_dopt.filterShowDotFiles; - updateSortSettingsAndReload(); - return true; - } - case R.id.action_folder_first: { - _dopt.sortFolderFirst = !_dopt.sortFolderFirst; - updateSortSettingsAndReload(); + case R.id.action_sort: { + updateSortSettings(); return true; } case R.id.action_import: { @@ -550,11 +471,6 @@ public boolean onOptionsItemSelected(final MenuItem item) { } return true; } - case R.id.action_save_sort_settings: { - _isSortOrderSaved = !_isSortOrderSaved; - updateSortSettingsAndReload(); - return true; - } } return false; @@ -695,7 +611,21 @@ private void updateSortSettings() { _dopt.sortFolderFirst = sortFolderFirst; _dopt.filterShowDotFiles = filterShowDotFiles; _isSortOrderSaved = saved; - updateSortSettingsAndReload(); + if (_isSortOrderSaved) { + final AppSettings.FolderSortOrder order = new AppSettings.FolderSortOrder(); + order.sortByType = _dopt.sortByType; + order.reverse = _dopt.sortReverse; + order.folderFirst = _dopt.sortFolderFirst; + order.showDotFiles = _dopt.filterShowDotFiles; + _appSettings.setFolderSortOrder(getCurrentFolder(), order); + } else { + _appSettings.setFolderSortOrder(getCurrentFolder(), null); + _appSettings.setFileBrowserSortByType(_dopt.sortByType); + _appSettings.setFileBrowserSortReverse(_dopt.sortReverse); + _appSettings.setFileBrowserSortFolderFirst(_dopt.sortFolderFirst); + _appSettings.setFileBrowserFilterShowDotFiles(_dopt.filterShowDotFiles); + } + reloadCurrentFolder(); // Ui will be updated by onFsViewerDoUiUpdate after the load }); } } diff --git a/app/src/main/res/menu/filesystem__menu.xml b/app/src/main/res/menu/filesystem__menu.xml index 833243fb13..b9639cddea 100644 --- a/app/src/main/res/menu/filesystem__menu.xml +++ b/app/src/main/res/menu/filesystem__menu.xml @@ -85,64 +85,7 @@ android:layout_width="match_parent" android:icon="@drawable/ic_sort_black_24dp" android:title="@string/sort_by" - app:showAsAction="always"> - - - - - - - - - - - - - - - - - + app:showAsAction="always" /> Date: Sat, 4 Jan 2025 15:42:52 -0800 Subject: [PATCH 05/12] Cleanups to dialog --- .../markor/frontend/MarkorDialogFactory.java | 3 +- .../frontend/GsSearchOrCustomTextDialog.java | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java index 0babd42fb1..d7d71e0da3 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java @@ -1031,11 +1031,12 @@ public static void showFolderSortDialog( else if (GsFileUtils.SORT_BY_FILESIZE.equals(sortType)) dopt.preSelected.add(3); else if (GsFileUtils.SORT_BY_MIMETYPE.equals(sortType)) dopt.preSelected.add(4); - dopt.radioSet = new HashSet<>(Arrays.asList(1, 2, 3, 4)); + dopt.radioIndices = new HashSet<>(Arrays.asList(1, 2, 3, 4)); dopt.isMultiSelectEnabled = true; dopt.isSearchEnabled = false; dopt.titleText = R.string.sort_by; dopt.dialogWidthDp = WindowManager.LayoutParams.WRAP_CONTENT; + dopt.showCountInOkButton = false; dopt.positionCallback = (selection) -> { final boolean reverse = selection.contains(6); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java index 6bb0573cdd..1cd34e835c 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java @@ -43,7 +43,6 @@ import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; -import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; @@ -84,11 +83,15 @@ public static class DialogOptions { @Nullable public GsCallback.a1> positionCallback = null; + // For multi select public boolean isMultiSelectEnabled = false; + public Collection preSelected = null; // Indices of pre-selected items + public Collection radioIndices = null; // Only one item can be selected among these + public boolean showCountInOkButton = true; + public List data = null; public List highlightData = null; public List iconsForData; - public Collection radioSet = null; public CharSequence messageText = ""; public String defaultText = ""; public boolean isDarkDialog = false; @@ -100,7 +103,6 @@ public static class DialogOptions { public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT; public int searchInputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; public String extraFilter = null; - public Collection preSelected = null; public GsCallback.a1 highlighter = null; public GsCallback.a1 neutralButtonCallback = null; public GsCallback.a1 dismissCallback = null; @@ -172,7 +174,7 @@ private Adapter(final Context context, final DialogOptions dopt) { private int chooseLayout(final int pos) { if (_dopt.isMultiSelectEnabled) { - if (_dopt.radioSet != null && _dopt.radioSet.contains(pos)) { + if (_dopt.radioIndices != null && _dopt.radioIndices.contains(pos)) { return android.R.layout.simple_list_item_single_choice; } else { return android.R.layout.simple_list_item_multiple_choice; @@ -289,7 +291,6 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi // SearchView is currently constructed even if it isn't needed final View searchView = makeSearchView(activity, dopt); final EditText searchEditText = searchView.findViewWithTag("EDIT"); - searchEditText.addTextChangedListener(GsTextWatcherAdapter.after(listAdapter::filter)); if (dopt.isSearchEnabled) { mainLayout.addView(searchView); @@ -335,6 +336,18 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi // ========================================================================================= + final GsCallback.a0 setSelectAllButtonState = () -> { + if (selectAll != null) { + final boolean allVisibleSelected = listAdapter._selectedItems.containsAll(listAdapter._filteredItems); + ((Checkable) selectAll).setChecked(allVisibleSelected); + } + }; + + searchEditText.addTextChangedListener(GsTextWatcherAdapter.after((constraint) -> { + listAdapter.filter(constraint); + setSelectAllButtonState.callback(); + })); + // Ok button only present under these circumstances final boolean isSearchOk = dopt.callback != null && dopt.isSearchEnabled; final boolean isMultiSelOk = dopt.positionCallback != null && dopt.isMultiSelectEnabled; @@ -418,7 +431,7 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi final Button okButton = dialog.getButton(Dialog.BUTTON_POSITIVE); final GsCallback.a0 setOkButtonState = () -> { if (okButton != null) { - if (dopt.isMultiSelectEnabled) { + if (dopt.isMultiSelectEnabled && dopt.showCountInOkButton) { okButton.setText(okString + String.format(" (%d)", listAdapter._selectedItems.size())); } else { okButton.setText(okString); @@ -428,21 +441,17 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi // Set ok button text initially setOkButtonState.callback(); - final GsCallback.a0 setSelectAllButtonState = () -> { - if (selectAll != null) { - ((Checkable) selectAll).setChecked(listAdapter._selectedItems.size() >= dopt.data.size()); - } - }; // Set select all button state initially setSelectAllButtonState.callback(); if (selectAll != null && dopt.isMultiSelectEnabled) { selectAll.setOnClickListener((v) -> { - if (listAdapter._selectedItems.size() < dopt.data.size()) { - listAdapter._selectedItems.addAll(GsCollectionUtils.range(dopt.data.size())); + final boolean allVisibleSelected = listAdapter._selectedItems.containsAll(listAdapter._filteredItems); + if (!allVisibleSelected) { + listAdapter._selectedItems.addAll(listAdapter._filteredItems); } else { - listAdapter._selectedItems.clear(); + listAdapter._selectedItems.removeAll(listAdapter._filteredItems); } listAdapter.notifyDataSetChanged(); setOkButtonState.callback(); @@ -460,8 +469,8 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi listAdapter._selectedItems.remove(index); } else { listAdapter._selectedItems.add(index); - if (dopt.radioSet != null && dopt.radioSet.contains(index)) { - for (int i : dopt.radioSet) { + if (dopt.radioIndices != null && dopt.radioIndices.contains(index)) { + for (int i : dopt.radioIndices) { if (i != index) { listAdapter._selectedItems.remove(i); } @@ -527,7 +536,7 @@ private static View makeTitleView(final Context context, final DialogOptions dop LinearLayout.LayoutParams.WRAP_CONTENT)); } - if (dopt.isMultiSelectEnabled && dopt.radioSet == null) { + if (dopt.isMultiSelectEnabled && dopt.radioIndices == null) { // Using a multiple choice text view as a selectable checkbox button // Requires no styling to match the existing check boxes final LayoutInflater inflater = LayoutInflater.from(context); From 2f6cfcbcb663055f78cd3a7dc4fa33973668ab4c Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Sun, 5 Jan 2025 23:06:57 -0800 Subject: [PATCH 06/12] New approach to dialog using change callback --- .../markdown/MarkdownActionButtons.java | 7 +- .../markor/frontend/MarkorDialogFactory.java | 110 +++++++++--- .../filebrowser/MarkorFileBrowserFactory.java | 6 +- .../gsantner/markor/model/AppSettings.java | 161 +++++------------- .../net/gsantner/opoc/format/GsTextUtils.java | 48 ++++++ .../frontend/GsSearchOrCustomTextDialog.java | 33 ++-- .../filebrowser/GsFileBrowserFragment.java | 49 ++---- .../filebrowser/GsFileBrowserListAdapter.java | 5 +- .../filebrowser/GsFileBrowserOptions.java | 8 +- .../net/gsantner/opoc/util/GsFileUtils.java | 49 +++++- app/src/main/res/values/strings.xml | 1 + .../writeily/widget/WrFilesWidgetFactory.java | 4 +- 12 files changed, 253 insertions(+), 228 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java index 9224b0b995..897c904949 100644 --- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java +++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java @@ -246,14 +246,13 @@ public boolean isValid() { public static Link extract(final CharSequence text, final int pos) { final int[] sel = TextViewUtils.getLineSelection(text, pos); - if (sel != null && sel[0] != -1 && sel[1] != -1) { + if (sel[0] != -1 && sel[1] != -1) { final String line = text.subSequence(sel[0], sel[1]).toString(); final Matcher m = MarkdownSyntaxHighlighter.LINK.matcher(line); - final int po = pos - sel[0]; while (m.find()) { - final int start = m.start(), end = m.end(); - if (start <= po && end >= po) { + final int start = m.start() + sel[0], end = m.end() + sel[0]; + if (start <= pos && end >= pos) { final boolean isImage = m.group(1) != null; return new Link(m.group(2), m.group(3), isImage, start, end); } diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java index d7d71e0da3..d89b534615 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java @@ -60,8 +60,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; @@ -1000,55 +1002,109 @@ public static void showInsertSnippetDialog(final Activity activity, final GsCall public static void showFolderSortDialog( final Activity activity, - final String sortType, - final boolean isReverse, - final boolean isFoldersFirst, - final boolean isDotFiles, - final boolean isSaved, - final GsCallback.a5 callback + final GsFileUtils.SortOrder currentOrder, + final GsFileUtils.SortOrder globalOrder, + final GsCallback.a1 callback ) { final DialogOptions dopt = new DialogOptions(); baseConf(activity, dopt); final List data = new ArrayList<>(); - data.add(activity.getString(R.string.save)); + final List icons = new ArrayList<>(); + final List layouts = new ArrayList<>(); + + data.add(activity.getString(R.string.folder_local)); + icons.add(R.drawable.ic_save_black_24dp); + layouts.add(android.R.layout.simple_list_item_multiple_choice); + data.add(activity.getString(R.string.name)); + icons.add(R.drawable.ic_sort_by_alpha_black_24dp); + layouts.add(android.R.layout.simple_list_item_single_choice); + data.add(activity.getString(R.string.date)); + icons.add(R.drawable.ic_date_range_black_24dp); + layouts.add(android.R.layout.simple_list_item_single_choice); + data.add(activity.getString(R.string.size)); + icons.add(R.drawable.ic_sd_card_black_24dp); + layouts.add(android.R.layout.simple_list_item_single_choice); + data.add(activity.getString(R.string.mime_type)); + icons.add(R.drawable.ic_baseline_plagiarism_24); + layouts.add(android.R.layout.simple_list_item_single_choice); + data.add(activity.getString(R.string.folder_first)); + icons.add(R.drawable.ic_baseline_rule_folder_24); + layouts.add(android.R.layout.simple_list_item_multiple_choice); + data.add(activity.getString(R.string.reverse_order)); + icons.add(R.drawable.ic_baseline_arrow_upward_24); + layouts.add(android.R.layout.simple_list_item_multiple_choice); + data.add(activity.getString(R.string.dotfiles)); + icons.add(R.drawable.ic_filter_center_focus_black_24dp); + layouts.add(android.R.layout.simple_list_item_multiple_choice); + dopt.data = data; + dopt.iconsForData = icons; + dopt.listItemLayouts = layouts; dopt.preSelected = new HashSet<>(); - if (isReverse) dopt.preSelected.add(6); - if (isFoldersFirst) dopt.preSelected.add(5); - if (isDotFiles) dopt.preSelected.add(7); - if (isSaved) dopt.preSelected.add(0); - if (GsFileUtils.SORT_BY_NAME.equals(sortType)) dopt.preSelected.add(1); - else if (GsFileUtils.SORT_BY_MTIME.equals(sortType)) dopt.preSelected.add(2); - else if (GsFileUtils.SORT_BY_FILESIZE.equals(sortType)) dopt.preSelected.add(3); - else if (GsFileUtils.SORT_BY_MIMETYPE.equals(sortType)) dopt.preSelected.add(4); - - dopt.radioIndices = new HashSet<>(Arrays.asList(1, 2, 3, 4)); + if (currentOrder.isFolderLocal) dopt.preSelected.add(0); + if (currentOrder.folderFirst) dopt.preSelected.add(5); + if (currentOrder.reverse) dopt.preSelected.add(6); + if (currentOrder.showDotFiles) dopt.preSelected.add(7); + + final Map typeToPos = new HashMap<>(); + typeToPos.put(GsFileUtils.SORT_BY_NAME, 1); + typeToPos.put(GsFileUtils.SORT_BY_MTIME, 2); + typeToPos.put(GsFileUtils.SORT_BY_FILESIZE, 3); + typeToPos.put(GsFileUtils.SORT_BY_MIMETYPE, 4); + dopt.preSelected.add(GsCollectionUtils.getOrDefault(typeToPos, currentOrder.sortByType, 1)); + dopt.isMultiSelectEnabled = true; dopt.isSearchEnabled = false; dopt.titleText = R.string.sort_by; dopt.dialogWidthDp = WindowManager.LayoutParams.WRAP_CONTENT; dopt.showCountInOkButton = false; + dopt.showSelectAllButton = false; + + final Set prevSelection = new HashSet<>(dopt.preSelected); + final boolean[] resetGlobal = {false}; + final Set radioSet = new HashSet<>(Arrays.asList(1, 2, 3, 4)); + dopt.selectionChangedCallback = (selection) -> { + final Set added = GsCollectionUtils.setDiff(selection, prevSelection); + final Set removed = GsCollectionUtils.setDiff(prevSelection, selection); + if (globalOrder != null && currentOrder.isFolderLocal && removed.contains(0)) { + // Reset to global if folder local is unchecked + resetGlobal[0] = true; + selection.clear(); + if (globalOrder.folderFirst) selection.add(5); + if (globalOrder.reverse) selection.add(6); + if (globalOrder.showDotFiles) selection.add(7); + selection.add(GsCollectionUtils.getOrDefault(typeToPos, globalOrder.sortByType, 1)); + } else if (!Collections.disjoint(removed, radioSet)) { + // If a radio button is unchecked add it back + selection.addAll(removed); + } else if (!Collections.disjoint(added, radioSet)) { + // If a radio button is checked, remove all other radio buttons + selection.removeAll(GsCollectionUtils.setDiff(radioSet, added)); + } + prevSelection.clear(); + prevSelection.addAll(selection); + }; dopt.positionCallback = (selection) -> { - final boolean reverse = selection.contains(6); - final boolean foldersFirst = selection.contains(5); - final boolean dotFiles = selection.contains(7); - final String sortBy; - if (selection.contains(2)) sortBy = GsFileUtils.SORT_BY_MTIME; - else if (selection.contains(3)) sortBy = GsFileUtils.SORT_BY_FILESIZE; - else if (selection.contains(4)) sortBy = GsFileUtils.SORT_BY_MIMETYPE; - else sortBy = GsFileUtils.SORT_BY_NAME; - final boolean save = selection.contains(0); - callback.callback(sortBy, reverse, foldersFirst, dotFiles, save); + final GsFileUtils.SortOrder order = new GsFileUtils.SortOrder(); + order.isFolderLocal = selection.contains(0); + order.folderFirst = selection.contains(5); + order.reverse = selection.contains(6); + order.showDotFiles = selection.contains(7); + if (selection.contains(2)) order.sortByType = GsFileUtils.SORT_BY_MTIME; + else if (selection.contains(3)) order.sortByType = GsFileUtils.SORT_BY_FILESIZE; + else if (selection.contains(4)) order.sortByType = GsFileUtils.SORT_BY_MIMETYPE; + else order.sortByType = GsFileUtils.SORT_BY_NAME; + callback.callback(order); }; GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt); diff --git a/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java b/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java index 1572157712..0bd0377795 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/filebrowser/MarkorFileBrowserFactory.java @@ -72,12 +72,14 @@ public static GsFileBrowserOptions.Options prepareFsViewerOpts( opts.folderImage = R.drawable.ic_folder_white_24dp; opts.titleText = R.string.select; opts.mountedStorageFolder = cu.getStorageAccessFolder(context); + opts.sortOrder = appSettings.getFolderSortOrder(null); updateFsViewerOpts(opts, context, appSettings); return opts; } + // We update these because some of these settings can change public static void updateFsViewerOpts( final GsFileBrowserOptions.Options opts, final Context context, @@ -85,10 +87,6 @@ public static void updateFsViewerOpts( ) { appSettings = appSettings != null ? appSettings : ApplicationObject.settings(); - 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(); diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index 5a5090be47..90c1dcdd92 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -35,9 +35,6 @@ import net.gsantner.opoc.util.GsContextUtils; import net.gsantner.opoc.util.GsFileUtils; -import org.json.JSONArray; -import org.json.JSONObject; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -45,9 +42,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -263,91 +257,53 @@ public boolean isRecreateMainRequired() { private final String PREF_PREFIX_FOLDER_SORT_ORDER = "PREF_PREFIX_FOLDER_SORT_ORDER"; - public static class FolderSortOrder { - private final static String SORT_BY_KEY = "SORT_BY"; - private final static String REVERSE_KEY = "REVERSE"; - private final static String SHOW_DOT_FILES_KEY = "SHOW_DOT_FILES"; - private final static String FOLDER_FIRST_KEY = "FOLDER_FIRST"; - - public String sortByType = GsFileUtils.SORT_BY_NAME; - public boolean reverse = false; - public boolean showDotFiles = false; - public boolean folderFirst = true; - public boolean hasCustomOrder = false; - } - - public void setFolderSortOrder(final File folder, final @Nullable FolderSortOrder sortOrder) { - final String canonicalPath = GsFileUtils.getPath(folder); - - if (TextUtils.isEmpty(canonicalPath)) { + /** + * Set sort order for a folder or globally. + * Passing null as folder will set the global sort order. + * Passing null as sortOrder will remove the sort order for the folder (revert to global). + * + * @param folder Folder to set the sort order for + * @param sortOrder Sort order to set + */ + public void setFolderSortOrder(final @Nullable File folder, final @Nullable GsFileUtils.SortOrder sortOrder) { + if (folder == null && sortOrder == null) { return; } - final String key = PREF_PREFIX_FOLDER_SORT_ORDER + canonicalPath; + // Null folders have empty suffix + final String key = PREF_PREFIX_FOLDER_SORT_ORDER + GsFileUtils.getPath(folder); if (sortOrder == null) { remove(key); return; } - final Map order = new HashMap<>(); - order.put(FolderSortOrder.SORT_BY_KEY, sortOrder.sortByType != null ? sortOrder.sortByType : GsFileUtils.SORT_BY_NAME); - order.put(FolderSortOrder.REVERSE_KEY, String.valueOf(sortOrder.reverse)); - order.put(FolderSortOrder.SHOW_DOT_FILES_KEY, String.valueOf(sortOrder.showDotFiles)); - order.put(FolderSortOrder.FOLDER_FIRST_KEY, String.valueOf(sortOrder.folderFirst)); - - setString(key, mapToJsonString(order)); + setString(key, sortOrder.toString()); } - public FolderSortOrder getFolderSortOrder(final File folder) { + /** + * Get sort order for a folder or globally. + * If no sort order is set for the folder, the global sort order is returned. + * If folder is null, the global sort order is returned. + * + * @param folder + * @return + */ + public GsFileUtils.SortOrder getFolderSortOrder(final @Nullable File folder) { + // Null folders have empty suffix final String path = GsFileUtils.getPath(folder); final String key = PREF_PREFIX_FOLDER_SORT_ORDER + path; - final String json = getString(key, null); - - final FolderSortOrder sortOrder = new FolderSortOrder(); - if (GsTextUtils.isNullOrEmpty(path) || json == null) { - sortOrder.sortByType = getFileBrowserSortByType(); - sortOrder.reverse = isFileBrowserSortReverse(); - sortOrder.folderFirst = isFileBrowserSortFolderFirst(); - sortOrder.showDotFiles = isFileBrowserFilterShowDotFiles(); - sortOrder.hasCustomOrder = false; - } else { - final Map order = jsonStringToMap(getString(key, "{}")); - sortOrder.sortByType = order.get(FolderSortOrder.SORT_BY_KEY); - sortOrder.reverse = Boolean.parseBoolean(order.get(FolderSortOrder.REVERSE_KEY)); - sortOrder.showDotFiles = Boolean.parseBoolean(order.get(FolderSortOrder.SHOW_DOT_FILES_KEY)); - sortOrder.folderFirst = Boolean.parseBoolean(order.get(FolderSortOrder.FOLDER_FIRST_KEY)); - sortOrder.hasCustomOrder = true; - } - - return sortOrder; - } + String json = getString(key, null); - public String setFileBrowserSortByType(String v) { - setString(R.string.pref_key__file_browser__sort_by_type, v); - return v; - } - - public String getFileBrowserSortByType() { - return getString(R.string.pref_key__file_browser__sort_by_type, GsFileUtils.SORT_BY_NAME); - } - - public boolean setFileBrowserSortReverse(boolean value) { - setBool(R.string.pref_key__sort_reverse, value); - return value; - } - - public boolean isFileBrowserSortReverse() { - return getBool(R.string.pref_key__sort_reverse, false); - } + final boolean isFolderLocal = !GsTextUtils.isNullOrEmpty(path) && json != null; - public boolean setFileBrowserFilterShowDotFiles(boolean v) { - setBool(R.string.pref_key__show_dot_files_v2, v); - return v; - } + if (!isFolderLocal) { + json = getString(PREF_PREFIX_FOLDER_SORT_ORDER, null); + } - public boolean isFileBrowserFilterShowDotFiles() { - return getBool(R.string.pref_key__show_dot_files_v2, true); + final GsFileUtils.SortOrder order = GsFileUtils.SortOrder.fromString(json); + order.isFolderLocal = isFolderLocal; + return order; } public boolean isShowSettingsOptionInMainToolbar() { @@ -1078,33 +1034,33 @@ public List> getSnippetFiles() { public void setTypeTemplate(final @StringRes int format, final String template) { final String js = getString(R.string.pref_key__filetype_template_map, "{}"); - final Map map = jsonStringToMap(js); + final Map map = GsTextUtils.jsonStringToMap(js); map.put(_context.getString(format), template); - setString(R.string.pref_key__filetype_template_map, mapToJsonString(map)); + setString(R.string.pref_key__filetype_template_map, GsTextUtils.mapToJsonString(map)); } public @Nullable String getTypeTemplate(final @StringRes int format) { final String js = getString(R.string.pref_key__filetype_template_map, "{}"); - final Map map = jsonStringToMap(js); + final Map map = GsTextUtils.jsonStringToMap(js); return map.get(format == 0 ? "" : _context.getString(format)); } public void setTemplateTitleFormat(final String templateName, final String titleFormat) { final String js = getString(R.string.pref_key__template_title_format_map, "{}"); - final Map map = jsonStringToMap(js); + final Map map = GsTextUtils.jsonStringToMap(js); map.put(templateName, titleFormat); - setString(R.string.pref_key__template_title_format_map, mapToJsonString(map)); + setString(R.string.pref_key__template_title_format_map, GsTextUtils.mapToJsonString(map)); } public @Nullable String getTemplateTitleFormat(final String templateName) { final String js = getString(R.string.pref_key__template_title_format_map, "{}"); - final Map map = jsonStringToMap(js); + final Map map = GsTextUtils.jsonStringToMap(js); return map.get(templateName); } public Set getTitleFormats() { final String js = getString(R.string.pref_key__title_format_list, "[]"); - final Set formats = new LinkedHashSet<>(jsonStringToList(js)); + final Set formats = new LinkedHashSet<>(GsTextUtils.jsonStringToList(js)); formats.addAll(Arrays.asList( "`yyyy-MM-dd`-{{title}}", "{{date}}_{{title}}", @@ -1124,7 +1080,7 @@ public void saveTitleFormat(final String format, final int maxCount) { break; } } - setString(R.string.pref_key__title_format_list, toJsonString(updated)); + setString(R.string.pref_key__title_format_list, GsTextUtils.listToJsonString(updated)); } public void setFormatShareAsLink(final boolean asLink) { @@ -1134,43 +1090,4 @@ public void setFormatShareAsLink(final boolean asLink) { public boolean getFormatShareAsLink() { return getBool(R.string.pref_key__format_share_as_link, true); } - - private static String mapToJsonString(final Map map) { - return new JSONObject(map).toString(); - } - - private static Map jsonStringToMap(final String jsonString) { - final Map map = new LinkedHashMap<>(); - try { - final JSONObject jsonObject = new JSONObject(jsonString); - final Iterator keys = jsonObject.keys(); - - while (keys.hasNext()) { - String key = keys.next(); - String value = jsonObject.getString(key); - map.put(key, value); - } - } catch (Exception e) { - e.printStackTrace(); - } - return map; - } - - public String toJsonString(final Collection list) { - final JSONArray jsonArray = new JSONArray(list); - return jsonArray.toString(); - } - - public List jsonStringToList(final String jsonString) { - final List list = new ArrayList<>(); - try { - final JSONArray jsonArray = new JSONArray(jsonString); - for (int i = 0; i < jsonArray.length(); i++) { - list.add(jsonArray.getString(i)); - } - } catch (Exception e) { - e.printStackTrace(); - } - return list; - } } diff --git a/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java b/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java index 554402b708..587317f352 100644 --- a/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java +++ b/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java @@ -20,9 +20,13 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -446,4 +450,48 @@ public static boolean inRange(final int min, final int max, final int... values) } return true; } + + public static String mapToJsonString(final Map map) { + return new JSONObject(map).toString(); + } + + public static Map jsonStringToMap(final String jsonString) { + final Map map = new LinkedHashMap<>(); + + if (isNullOrEmpty(jsonString)) { + return map; + } + + try { + final JSONObject jsonObject = new JSONObject(jsonString); + final Iterator keys = jsonObject.keys(); + + while (keys.hasNext()) { + String key = keys.next(); + String value = jsonObject.getString(key); + map.put(key, value); + } + } catch (Exception e) { + e.printStackTrace(); + } + return map; + } + + public static String listToJsonString(final Collection list) { + final JSONArray jsonArray = new JSONArray(list); + return jsonArray.toString(); + } + + public static List jsonStringToList(final String jsonString) { + final List list = new ArrayList<>(); + try { + final JSONArray jsonArray = new JSONArray(jsonString); + for (int i = 0; i < jsonArray.length(); i++) { + list.add(jsonArray.getString(i)); + } + } catch (Exception e) { + e.printStackTrace(); + } + return list; + } } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java index 1cd34e835c..22d90d1565 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java @@ -86,11 +86,13 @@ public static class DialogOptions { // For multi select public boolean isMultiSelectEnabled = false; public Collection preSelected = null; // Indices of pre-selected items - public Collection radioIndices = null; // Only one item can be selected among these + public boolean showSelectAllButton = true; public boolean showCountInOkButton = true; + public GsCallback.a1> selectionChangedCallback = null; public List data = null; public List highlightData = null; + public List listItemLayouts = null; public List iconsForData; public CharSequence messageText = ""; public String defaultText = ""; @@ -173,12 +175,10 @@ private Adapter(final Context context, final DialogOptions dopt) { } private int chooseLayout(final int pos) { - if (_dopt.isMultiSelectEnabled) { - if (_dopt.radioIndices != null && _dopt.radioIndices.contains(pos)) { - return android.R.layout.simple_list_item_single_choice; - } else { - return android.R.layout.simple_list_item_multiple_choice; - } + if (_dopt.listItemLayouts != null && pos < _dopt.listItemLayouts.size()) { + return _dopt.listItemLayouts.get(pos); + } else if (_dopt.isMultiSelectEnabled) { + return android.R.layout.simple_list_item_multiple_choice; } else { return android.R.layout.simple_list_item_1; } @@ -353,12 +353,12 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi final boolean isMultiSelOk = dopt.positionCallback != null && dopt.isMultiSelectEnabled; final boolean isPlainDialog = dopt.callback != null && (dopt.data == null || dopt.data.isEmpty()); if (isSearchOk || isMultiSelOk || isPlainDialog) { + final boolean selectionChanged = !GsCollectionUtils.setEquals(dopt.preSelected, listAdapter._selectedItems); dialogBuilder.setPositiveButton(dopt.okButtonText, (dialogInterface, i) -> { final String searchText = dopt.isSearchEnabled ? searchEditText.getText().toString() : null; - if (dopt.positionCallback != null && !GsCollectionUtils.setEquals(dopt.preSelected, listAdapter._selectedItems)) { - // Position callback triggered when selection changed + if (dopt.positionCallback != null && (selectionChanged || dopt.callback == null)) { dopt.positionCallback.callback(new ArrayList<>(listAdapter._selectedItems)); - } else if (dopt.callback != null && (!dopt.isSearchEnabled || !TextUtils.isEmpty(searchText))) { + } else if (dopt.callback != null && !TextUtils.isEmpty(searchText)) { dopt.callback.callback(searchText); } }); @@ -469,13 +469,9 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi listAdapter._selectedItems.remove(index); } else { listAdapter._selectedItems.add(index); - if (dopt.radioIndices != null && dopt.radioIndices.contains(index)) { - for (int i : dopt.radioIndices) { - if (i != index) { - listAdapter._selectedItems.remove(i); - } - } - } + } + if (dopt.selectionChangedCallback != null) { + dopt.selectionChangedCallback.callback(listAdapter._selectedItems); } listAdapter.notifyDataSetChanged(); setOkButtonState.callback(); @@ -536,7 +532,8 @@ private static View makeTitleView(final Context context, final DialogOptions dop LinearLayout.LayoutParams.WRAP_CONTENT)); } - if (dopt.isMultiSelectEnabled && dopt.radioIndices == null) { + // Add select all button + if (dopt.isMultiSelectEnabled && dopt.showSelectAllButton) { // Using a multiple choice text view as a selectable checkbox button // Requires no styling to match the existing check boxes final LayoutInflater inflater = LayoutInflater.from(context); diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java index 5e980084cd..3b36360dc9 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java @@ -92,7 +92,6 @@ public static GsFileBrowserFragment newInstance() { private MarkorContextUtils _cu; private Toolbar _toolbar; private boolean _reloadRequiredOnResume = true; - private boolean _isSortOrderSaved = false; //######################## //## Methods @@ -186,12 +185,7 @@ public void onFsViewerFolderChange(final File newFolder) { _callback.onFsViewerFolderChange(newFolder); } - final AppSettings.FolderSortOrder order = _appSettings.getFolderSortOrder(newFolder); - _dopt.sortByType = order.sortByType; - _dopt.sortFolderFirst = order.folderFirst; - _dopt.sortReverse = order.reverse; - _dopt.filterShowDotFiles = order.showDotFiles; - _isSortOrderSaved = order.hasCustomOrder; + _dopt.sortOrder = _appSettings.getFolderSortOrder(newFolder); } @Override @@ -283,7 +277,7 @@ private void updateMenuItems() { final MenuItem sortItem = _fragmentMenu.findItem(R.id.action_sort); if (sortItem != null) { - _cu.tintDrawable(sortItem.getIcon(), _isSortOrderSaved ? GsFileBrowserListAdapter.FAVOURITE_COLOR : Color.WHITE); + _cu.tintDrawable(sortItem.getIcon(), _dopt.sortOrder.isFolderLocal ? GsFileBrowserListAdapter.FAVOURITE_COLOR : Color.WHITE); } } @@ -598,33 +592,20 @@ public GsFileBrowserOptions.Options getOptions() { } private void updateSortSettings() { - MarkorDialogFactory.showFolderSortDialog( - getActivity(), - _dopt.sortByType, - _dopt.sortReverse, - _dopt.sortFolderFirst, - _dopt.filterShowDotFiles, - _isSortOrderSaved, - (sortByType, sortReverse, sortFolderFirst, filterShowDotFiles, saved) -> { - _dopt.sortByType = sortByType; - _dopt.sortReverse = sortReverse; - _dopt.sortFolderFirst = sortFolderFirst; - _dopt.filterShowDotFiles = filterShowDotFiles; - _isSortOrderSaved = saved; - if (_isSortOrderSaved) { - final AppSettings.FolderSortOrder order = new AppSettings.FolderSortOrder(); - order.sortByType = _dopt.sortByType; - order.reverse = _dopt.sortReverse; - order.folderFirst = _dopt.sortFolderFirst; - order.showDotFiles = _dopt.filterShowDotFiles; - _appSettings.setFolderSortOrder(getCurrentFolder(), order); - } else { - _appSettings.setFolderSortOrder(getCurrentFolder(), null); - _appSettings.setFileBrowserSortByType(_dopt.sortByType); - _appSettings.setFileBrowserSortReverse(_dopt.sortReverse); - _appSettings.setFileBrowserSortFolderFirst(_dopt.sortFolderFirst); - _appSettings.setFileBrowserFilterShowDotFiles(_dopt.filterShowDotFiles); + final GsFileUtils.SortOrder globalOrder = _appSettings.getFolderSortOrder(null); + MarkorDialogFactory.showFolderSortDialog(getActivity(), _dopt.sortOrder, globalOrder, + (order) -> { + final File currentFolder = getCurrentFolder(); + + // Erase local sort order if local is unset + if (_dopt.sortOrder.isFolderLocal && !order.isFolderLocal) { + _appSettings.setFolderSortOrder(currentFolder, null); } + + // Set new sort order to folder or global as needed + _appSettings.setFolderSortOrder(order.isFolderLocal ? currentFolder : null, _dopt.sortOrder); + + _dopt.sortOrder = order; reloadCurrentFolder(); // Ui will be updated by onFsViewerDoUiUpdate after the load }); } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java index 4228335e37..10ffd15615 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java @@ -49,7 +49,6 @@ import java.io.FilenameFilter; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -717,7 +716,7 @@ private synchronized void _loadFolder(final boolean folderChanged, final @Nullab // Don't sort recent or virtual root items - use the default order if (isCurrentFolderSortable()) { - GsFileUtils.sortFiles(newData, _dopt.sortByType, _dopt.sortFolderFirst, _dopt.sortReverse); + GsFileUtils.sortFiles(newData, _dopt.sortOrder); } // Testing if modtimes have changed (modtimes generally only increase) @@ -784,7 +783,7 @@ private boolean canWrite(File file) { public boolean accept(File dir, String filename) { final File f = new File(dir, filename); final boolean filterYes = f.isDirectory() || _dopt.fileOverallFilter == null || _dopt.fileOverallFilter.callback(_context, f); - final boolean dotYes = _dopt.filterShowDotFiles || !filename.startsWith(".") && !isAccessoryFolder(dir, filename, f); + final boolean dotYes = _dopt.sortOrder.showDotFiles || !filename.startsWith(".") && !isAccessoryFolder(dir, filename, f); final boolean selFileYes = _dopt.doSelectFile || f.isDirectory(); return filterYes && dotYes && selFileYes; } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java index 3e7eb15aec..e2ac8cedfd 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserOptions.java @@ -52,7 +52,6 @@ public static class Options { mountedStorageFolder = null, startFolder = null; public String requestId = "show_dialog"; - public String sortByType = GsFileUtils.SORT_BY_NAME; public String descriptionFormat = null; @@ -62,10 +61,7 @@ public static class Options { doSelectFile = false, doSelectMultiple = false; - public boolean sortFolderFirst = true, - sortReverse = false, - descModtimeInsteadOfParent = false, - filterShowDotFiles = true; + public boolean descModtimeInsteadOfParent = false; public int itemSidePadding = 16; // dp @@ -80,6 +76,8 @@ public static class Options { newDirButtonEnable = true, dismissAfterCallback = true; + public GsFileUtils.SortOrder sortOrder = new GsFileUtils.SortOrder(); + public GsCallback.b2 fileOverallFilter = (context, file) -> true; @StringRes diff --git a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java index 31636f8446..339189428a 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java @@ -17,6 +17,7 @@ import android.util.Log; import android.util.Pair; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; @@ -55,6 +56,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -772,22 +774,51 @@ private static String makeSortKey(final String sortBy, final File file) { } } - public static void sortFiles( - final Collection filesToSort, - final String sortBy, - final boolean folderFirst, - final boolean reverse - ) { + public static class SortOrder { + public String sortByType = SORT_BY_NAME; + public boolean reverse = false; + public boolean showDotFiles = false; + public boolean folderFirst = true; + public boolean isFolderLocal = false; + + private final static String SORT_BY_KEY = "SORT_BY"; + private final static String REVERSE_KEY = "REVERSE"; + private final static String SHOW_DOT_FILES_KEY = "SHOW_DOT_FILES"; + private final static String FOLDER_FIRST_KEY = "FOLDER_FIRST"; + + @NonNull + @Override + public String toString() { + final Map map = new HashMap<>(); + map.put(SORT_BY_KEY, sortByType); + map.put(REVERSE_KEY, String.valueOf(reverse)); + map.put(SHOW_DOT_FILES_KEY, String.valueOf(showDotFiles)); + map.put(FOLDER_FIRST_KEY, String.valueOf(folderFirst)); + return GsTextUtils.mapToJsonString(map); + } + + public static SortOrder fromString(final String json) { + final SortOrder fso = new SortOrder(); + final Map map = GsTextUtils.jsonStringToMap(json); + fso.sortByType = GsCollectionUtils.getOrDefault(map, SORT_BY_KEY, SORT_BY_NAME); + fso.reverse = Boolean.parseBoolean(GsCollectionUtils.getOrDefault(map, REVERSE_KEY, "false")); + fso.showDotFiles = Boolean.parseBoolean(GsCollectionUtils.getOrDefault(map, SHOW_DOT_FILES_KEY, "false")); + fso.folderFirst = Boolean.parseBoolean(GsCollectionUtils.getOrDefault(map, FOLDER_FIRST_KEY, "true")); + return fso; + } + } + + public static void sortFiles(final Collection filesToSort, final SortOrder order) { if (filesToSort != null && !filesToSort.isEmpty()) { try { final boolean copy = !(filesToSort instanceof List); final List sortable = copy ? new ArrayList<>(filesToSort) : (List) filesToSort; - GsCollectionUtils.keySort(sortable, (f) -> makeSortKey(sortBy, f)); - if (reverse) { + GsCollectionUtils.keySort(sortable, (f) -> makeSortKey(order.sortByType, f)); + if (order.reverse) { Collections.reverse(sortable); } - if (folderFirst) { + if (order.folderFirst) { GsCollectionUtils.keySort(sortable, (f) -> !f.isDirectory()); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e1b217a114..87fe8ee78b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -483,4 +483,5 @@ work. If not, see . Capitalize Words (Ex: a note->A Note) Capitalize Sentences (Ex: case->Case) Indent lines with TAB key + Folder local diff --git a/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java b/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java index 648fadd9f6..39f4f4c855 100644 --- a/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java +++ b/app/thirdparty/java/other/writeily/widget/WrFilesWidgetFactory.java @@ -51,7 +51,7 @@ public void onDataSetChanged() { _widgetFilesList.clear(); final File dir = WrWidgetConfigure.getWidgetDirectory(_context, _appWidgetId); final AppSettings as = ApplicationObject.settings(); - final AppSettings.FolderSortOrder order = as.getFolderSortOrder(dir); + final GsFileUtils.SortOrder order = as.getFolderSortOrder(dir); if (dir.equals(GsFileBrowserListAdapter.VIRTUAL_STORAGE_RECENTS)) { _widgetFilesList.addAll(ApplicationObject.settings().getRecentFiles()); @@ -64,7 +64,7 @@ public void onDataSetChanged() { _widgetFilesList.addAll(all != null ? Arrays.asList(all) : Collections.emptyList()); } - GsFileUtils.sortFiles(_widgetFilesList, order.sortByType, order.folderFirst, order.reverse); + GsFileUtils.sortFiles(_widgetFilesList, order); } @Override From 342d83a34dde37e909830a9402eea31b008ce086 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Mon, 6 Jan 2025 22:51:41 -0800 Subject: [PATCH 07/12] Must check in the callback :) --- .../opoc/frontend/GsSearchOrCustomTextDialog.java | 2 +- .../java/net/gsantner/opoc/util/GsCollectionUtils.java | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java index 22d90d1565..d8d964c620 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java @@ -353,9 +353,9 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi final boolean isMultiSelOk = dopt.positionCallback != null && dopt.isMultiSelectEnabled; final boolean isPlainDialog = dopt.callback != null && (dopt.data == null || dopt.data.isEmpty()); if (isSearchOk || isMultiSelOk || isPlainDialog) { - final boolean selectionChanged = !GsCollectionUtils.setEquals(dopt.preSelected, listAdapter._selectedItems); dialogBuilder.setPositiveButton(dopt.okButtonText, (dialogInterface, i) -> { final String searchText = dopt.isSearchEnabled ? searchEditText.getText().toString() : null; + final boolean selectionChanged = !GsCollectionUtils.setEquals(dopt.preSelected, listAdapter._selectedItems); if (dopt.positionCallback != null && (selectionChanged || dopt.callback == null)) { dopt.positionCallback.callback(new ArrayList<>(listAdapter._selectedItems)); } else if (dopt.callback != null && !TextUtils.isEmpty(searchText)) { diff --git a/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java index 9a53ad41f5..81b8787528 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java @@ -128,14 +128,8 @@ public static Set setDiff(final Collection a, final Collection b) { /** * Check if 2 collections have the same elements */ - public static boolean setEquals(Collection a, Collection b) { - a = a != null ? a : Collections.emptySet(); - b = b != null ? b : Collections.emptySet(); - - a = a instanceof Set ? a : new HashSet<>(a); - b = b instanceof Set ? b : new HashSet<>(b); - - return a.equals(b); + public static boolean setEquals(final Collection a, final Collection b) { + return (a == b) || (a != null && b != null && a.size() == b.size() && a.containsAll(b)); } /** From 3237d18c45f78f94d4debdc40db1066734aff0f8 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Fri, 10 Jan 2025 08:51:50 -0800 Subject: [PATCH 08/12] Fixes, wrap improvements --- .../opoc/frontend/filebrowser/GsFileBrowserFragment.java | 8 ++++---- app/src/main/res/layout/document__fragment__edit.xml | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java index 3b36360dc9..3ef8547f66 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java @@ -595,18 +595,18 @@ private void updateSortSettings() { final GsFileUtils.SortOrder globalOrder = _appSettings.getFolderSortOrder(null); MarkorDialogFactory.showFolderSortDialog(getActivity(), _dopt.sortOrder, globalOrder, (order) -> { - final File currentFolder = getCurrentFolder(); - // Erase local sort order if local is unset + final File currentFolder = getCurrentFolder(); if (_dopt.sortOrder.isFolderLocal && !order.isFolderLocal) { _appSettings.setFolderSortOrder(currentFolder, null); } // Set new sort order to folder or global as needed + _dopt.sortOrder = order; _appSettings.setFolderSortOrder(order.isFolderLocal ? currentFolder : null, _dopt.sortOrder); - _dopt.sortOrder = order; - reloadCurrentFolder(); // Ui will be updated by onFsViewerDoUiUpdate after the load + // Ui will be updated by onFsViewerDoUiUpdate after the load + reloadCurrentFolder(); }); } } diff --git a/app/src/main/res/layout/document__fragment__edit.xml b/app/src/main/res/layout/document__fragment__edit.xml index ebedcafed5..afefc8aded 100644 --- a/app/src/main/res/layout/document__fragment__edit.xml +++ b/app/src/main/res/layout/document__fragment__edit.xml @@ -39,6 +39,9 @@ android:paddingTop="@dimen/activity_vertical_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/editor_bottom_margin" + android:breakStrategy="balanced" + android:lineBreakStyle="normal" + android:hyphenationFrequency="normalFast" android:scrollbars="none" android:textCursorDrawable="@drawable/cursor_accent" /> From b4d1d1a693820b504dff8dcea77a1713792331c8 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Fri, 10 Jan 2025 22:06:26 -0800 Subject: [PATCH 09/12] Reverted reflow settings --- .../gsantner/markor/activity/DocumentEditAndViewFragment.java | 1 + app/src/main/res/layout/document__fragment__edit.xml | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java index 25946727c5..db5620357e 100644 --- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java +++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java @@ -207,6 +207,7 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Do not need to send contents to accessibility _hlEditor.setImportantForAccessibility(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS); + } // Various settings diff --git a/app/src/main/res/layout/document__fragment__edit.xml b/app/src/main/res/layout/document__fragment__edit.xml index afefc8aded..ebedcafed5 100644 --- a/app/src/main/res/layout/document__fragment__edit.xml +++ b/app/src/main/res/layout/document__fragment__edit.xml @@ -39,9 +39,6 @@ android:paddingTop="@dimen/activity_vertical_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/editor_bottom_margin" - android:breakStrategy="balanced" - android:lineBreakStyle="normal" - android:hyphenationFrequency="normalFast" android:scrollbars="none" android:textCursorDrawable="@drawable/cursor_accent" /> From b35b3d50778ca46ae3e58510c30fadd383f9a745 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Fri, 10 Jan 2025 22:08:09 -0800 Subject: [PATCH 10/12] Fixed diff --- .../gsantner/markor/activity/DocumentEditAndViewFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java index db5620357e..25946727c5 100644 --- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java +++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java @@ -207,7 +207,6 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Do not need to send contents to accessibility _hlEditor.setImportantForAccessibility(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS); - } // Various settings From 2f6c5c177c4d5413a0bbca314f8d9696ded352dc Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Fri, 10 Jan 2025 22:17:46 -0800 Subject: [PATCH 11/12] Better icon --- .../java/net/gsantner/markor/frontend/MarkorDialogFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java index d89b534615..01601d3b3b 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java @@ -1042,7 +1042,7 @@ public static void showFolderSortDialog( layouts.add(android.R.layout.simple_list_item_multiple_choice); data.add(activity.getString(R.string.dotfiles)); - icons.add(R.drawable.ic_filter_center_focus_black_24dp); + icons.add(R.drawable.ic_regex_black_24dp); layouts.add(android.R.layout.simple_list_item_multiple_choice); dopt.data = data; From 7299c7db10f8a8ddaf5ac209cc1a48595d5d0efe Mon Sep 17 00:00:00 2001 From: Gregor Santner Date: Wed, 5 Feb 2025 19:14:21 +0100 Subject: [PATCH 12/12] optimize code --- .../gsantner/markor/format/orgmode/OrgmodeActionButtons.java | 1 - .../markor/format/orgmode/OrgmodeReplacePatternGenerator.java | 3 --- .../gsantner/markor/frontend/textview/HighlightingEditor.java | 1 - app/src/main/java/net/gsantner/markor/model/AppSettings.java | 1 - .../main/java/net/gsantner/opoc/util/GsCollectionUtils.java | 1 - 5 files changed, 7 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java index 552e1ee44e..8c21a214c2 100644 --- a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java +++ b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java @@ -7,7 +7,6 @@ import net.gsantner.markor.R; import net.gsantner.markor.format.ActionButtonBase; -import net.gsantner.markor.format.orgmode.OrgmodeReplacePatternGenerator; import net.gsantner.markor.frontend.textview.AutoTextFormatter; import net.gsantner.markor.model.Document; diff --git a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeReplacePatternGenerator.java b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeReplacePatternGenerator.java index 0c65d46d52..a246520eb7 100644 --- a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeReplacePatternGenerator.java +++ b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeReplacePatternGenerator.java @@ -7,12 +7,9 @@ #########################################################*/ package net.gsantner.markor.format.orgmode; -import android.util.Log; - import net.gsantner.markor.format.ActionButtonBase; import net.gsantner.markor.frontend.textview.AutoTextFormatter; import net.gsantner.markor.frontend.textview.ReplacePatternGeneratorHelper; -import net.gsantner.opoc.format.GsTextUtils; import java.util.ArrayList; import java.util.List; diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java index 66b86fd2bd..939f6e0522 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java @@ -36,7 +36,6 @@ import net.gsantner.markor.R; import net.gsantner.markor.activity.MainActivity; import net.gsantner.markor.model.AppSettings; -import net.gsantner.markor.util.TextCasingUtils; import net.gsantner.opoc.format.GsTextUtils; import net.gsantner.opoc.wrapper.GsCallback; import net.gsantner.opoc.wrapper.GsTextWatcherAdapter; diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index 90c1dcdd92..7dce197558 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -13,7 +13,6 @@ import android.graphics.Color; import android.os.Build; import android.os.Environment; -import android.text.TextUtils; import android.util.Pair; import androidx.annotation.ColorRes; diff --git a/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java index 81b8787528..cfdd4342be 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsCollectionUtils.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map;