Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add Option to sort folders alphabetical #154

Merged
merged 1 commit into from
Apr 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions res/runtime/dictionary.properties
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ CustomizeCommandBar.label = Customize command bar
ToggleStatusBar.show = Show status bar
ToggleStatusBar.hide = Hide status bar
ToggleShowFoldersFirst.label = Show folders first
ToggleFoldersAlwaysAlphabetical.label = Sort Folders always alphabetical
ToggleTree.label = Show tree view
ToggleSinglePanel.label = Toggle single panel
PopupLeftDriveButton.label = Change left folder
Expand Down
1 change: 1 addition & 0 deletions res/runtime/dictionary_de_DE.properties
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ CustomizeCommandBar.label = Kommandozeile anpassen
ToggleStatusBar.show = Statusleiste anzeigen
ToggleStatusBar.hide = Statusleiste verbergen
ToggleShowFoldersFirst.label = Ordner zuerst anzeigen
ToggleFoldersAlwaysAlphabetical.label = Ordner immer alphabetisch ordnen
ToggleTree.label = Zeige Baumansicht
PopupLeftDriveButton.label = Linken Ordner ändern
PopupRightDriveButton.label = Rechten Ordner ändern
Expand Down
23 changes: 19 additions & 4 deletions src/main/com/mucommander/commons/file/util/FileComparator.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class FileComparator implements Comparator<AbstractFile> {
private boolean ascending;
/** Specifies whether directories should precede files or be handled as regular files */
private boolean directoriesFirst;
/** Specifies whether directories always alphabetical sorted */
private boolean foldersAlwaysAlphabetical;

/** Criterion for filename comparison. */
public final static int NAME_CRITERION = 0;
Expand Down Expand Up @@ -63,16 +65,18 @@ public class FileComparator implements Comparator<AbstractFile> {
* @param criterion comparison criterion, see constant fields
* @param ascending if true, ascending order will be used, descending order otherwise
* @param directoriesFirst specifies whether directories should precede files or be handled as regular files
* @param foldersAlwaysAlphabetical specifies wether directories are sorted always alphabetical if they stay first
*/
public FileComparator(int criterion, boolean ascending, boolean directoriesFirst, QuickSearch quickSearch) {
public FileComparator(int criterion, boolean ascending, boolean directoriesFirst, boolean foldersAlwaysAlphabetical, QuickSearch quickSearch) {
this.criterion = criterion;
this.ascending = ascending;
this.directoriesFirst = directoriesFirst;
this.foldersAlwaysAlphabetical = foldersAlwaysAlphabetical;
this.quickSearch = quickSearch;
}

public FileComparator(int criterion, boolean ascending, boolean directoriesFirst) {
this(criterion, ascending, directoriesFirst, null);
public FileComparator(int criterion, boolean ascending, boolean directoriesFirst, boolean foldersAlwaysAlphabetical) {
this(criterion, ascending, directoriesFirst, foldersAlwaysAlphabetical, null);
}


Expand Down Expand Up @@ -268,15 +272,26 @@ public int compare(AbstractFile f1, AbstractFile f2) {

boolean is1Directory = f1.isDirectory();
boolean is2Directory = f2.isDirectory();
long diff;

if (directoriesFirst) {
if (is1Directory && !is2Directory) {
return -1; // ascending has no effect on the result (a directory is always first) so let's return
} else if (is2Directory && !is1Directory) {
return 1; // ascending has no effect on the result (a directory is always first) so let's return
}
if ((foldersAlwaysAlphabetical) && (is1Directory && is2Directory))
{

diff = compareStrings(f1.getName(), f2.getName(), true);
if (diff == 0) {
// Case-sensitive name comparison
diff = compareStrings(f1.getName(), f2.getName(), false);
}
return (int) diff;
}
// At this point, either both files are directories or none of them are
}
long diff;

if (criterion == SIZE_CRITERION) {
// Consider that directories have a size of 0
Expand Down
1 change: 1 addition & 0 deletions src/main/com/mucommander/conf/MuPreference.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public enum MuPreference {
AUTO_SIZE_COLUMNS(MuPreferences.AUTO_SIZE_COLUMNS),
USE_SYSTEM_FILE_ICONS(MuPreferences.USE_SYSTEM_FILE_ICONS),
SHOW_FOLDERS_FIRST(MuPreferences.SHOW_FOLDERS_FIRST),
FOLDERS_ALWAYS_ALPHABETICAL(MuPreferences.FOLDERS_ALWAYS_ALPHABETICAL),
SHOW_QUICK_SEARCH_MATCHES_FIRST(MuPreferences.SHOW_QUICK_SEARCH_MATCHES_FIRST),
QUICK_SEARCH_TIMEOUT(MuPreferences.QUICK_SEARCH_TIMEOUT),
CD_FOLLOWS_SYMLINKS(MuPreferences.CD_FOLLOWS_SYMLINKS),
Expand Down
4 changes: 4 additions & 0 deletions src/main/com/mucommander/conf/MuPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,12 @@ public class MuPreferences implements MuPreferencesAPI {
public static final String DEFAULT_USE_SYSTEM_FILE_ICONS = FileIcons.USE_SYSTEM_ICONS_APPLICATIONS;
/** Controls whether folders are displayed first in the FileTable or mixed with regular files. */
public static final String SHOW_FOLDERS_FIRST = FILE_TABLE_SECTION + '.' + "show_folders_first";
/** Controls whether folders are always sorted alphabetical, doesn't matter which sort is set for the files. */
public static final String FOLDERS_ALWAYS_ALPHABETICAL = FILE_TABLE_SECTION + '.' + "folders_always_alphabetical";
/** Default value for 'Show folders first' option. */
public static final boolean DEFAULT_SHOW_FOLDERS_FIRST = true;
/** Default value for 'Folders always alphabetical' option. */
public static final boolean DEFAULT_FOLDERS_ALWAYS_ALPHABETICAL = true;
/** Controls whether symlinks should be followed when changing directory. */
public static final String CD_FOLLOWS_SYMLINKS = FILE_TABLE_SECTION + '.' + "cd_follows_symlinks";
/** Default value for 'Follow symlinks when changing directory' option. */
Expand Down
1 change: 1 addition & 0 deletions src/main/com/mucommander/ui/action/ActionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ public static void registerActions() {
registerAction(new ToggleOwnerColumnAction.Descriptor());
registerAction(new TogglePermissionsColumnAction.Descriptor());
registerAction(new ToggleShowFoldersFirstAction.Descriptor());
registerAction(new ToggleFoldersAlwaysAlphabeticalAction.Descriptor());
registerAction(new ToggleSizeColumnAction.Descriptor());
registerAction(new ToggleStatusBarAction.Descriptor());
registerAction(new ToggleToolBarAction.Descriptor());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* This file is part of muCommander, http://www.mucommander.com
* Copyright (C) 2002-2012 Maxence Bernard
*
* muCommander is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* muCommander is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.mucommander.ui.action.impl;

import com.mucommander.conf.MuConfigurations;
import com.mucommander.conf.MuPreference;
import com.mucommander.ui.action.AbstractActionDescriptor;
import com.mucommander.ui.action.ActionCategory;
import com.mucommander.ui.action.ActionDescriptor;
import com.mucommander.ui.action.MuAction;
import com.mucommander.ui.main.MainFrame;
import com.mucommander.ui.main.table.FileTable;

import javax.swing.*;
import java.util.Map;

/**
* This action toggles the 'Show folders first' option, which controls whether folders are displayed first in the
* FileTable or mixed with regular files.
*
* @author Maxence Bernard
*/
public class ToggleFoldersAlwaysAlphabeticalAction extends MuAction {

ToggleFoldersAlwaysAlphabeticalAction(MainFrame mainFrame, Map<String, Object> properties) {
super(mainFrame, properties);
}

@Override
public void performAction() {
FileTable activeTable = mainFrame.getActiveTable();
boolean foldersAlwaysAlphabetical = !activeTable.getSortInfo().getFoldersAlwaysAlphabetical();
activeTable.setFoldersAlwaysAlphabetical(foldersAlwaysAlphabetical);
MuConfigurations.getPreferences().setVariable(MuPreference.FOLDERS_ALWAYS_ALPHABETICAL, foldersAlwaysAlphabetical);
}

@Override
public ActionDescriptor getDescriptor() {
return new Descriptor();
}


public static final class Descriptor extends AbstractActionDescriptor {
public static final String ACTION_ID = "ToggleFoldersAlwaysAlphabetical";

public String getId() { return ACTION_ID; }

public ActionCategory getCategory() { return ActionCategory.VIEW; }

public KeyStroke getDefaultAltKeyStroke() { return null; }

public KeyStroke getDefaultKeyStroke() { return null; }

public MuAction createAction(MainFrame mainFrame, Map<String,Object> properties) {
return new ToggleFoldersAlwaysAlphabeticalAction(mainFrame, properties);
}
}
}
7 changes: 6 additions & 1 deletion src/main/com/mucommander/ui/main/menu/MainMenuBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public class MainMenuBar extends JMenuBar implements ActionListener, MenuListene
private JCheckBoxMenuItem[] toggleColumnItems = new TCheckBoxMenuItem[Column.values().length];
private JCheckBoxMenuItem toggleToggleAutoSizeItem;
private JCheckBoxMenuItem toggleShowFoldersFirstItem;
private JCheckBoxMenuItem toggleFoldersAlwaysAlphabeticalItem;
private JCheckBoxMenuItem toggleShowHiddenFilesItem;
private JCheckBoxMenuItem toggleTreeItem;
private JCheckBoxMenuItem toggleSinglePanel;
Expand Down Expand Up @@ -244,6 +245,7 @@ public MainMenuBar(MainFrame mainFrame) {
viewMenu.add(new TMenuSeparator());

toggleShowFoldersFirstItem = MenuToolkit.addCheckBoxMenuItem(viewMenu, ActionManager.getActionInstance(ToggleShowFoldersFirstAction.Descriptor.ACTION_ID, mainFrame), menuItemMnemonicHelper);
toggleFoldersAlwaysAlphabeticalItem = MenuToolkit.addCheckBoxMenuItem(viewMenu, ActionManager.getActionInstance(ToggleFoldersAlwaysAlphabeticalAction.Descriptor.ACTION_ID, mainFrame), menuItemMnemonicHelper);
toggleShowHiddenFilesItem = MenuToolkit.addCheckBoxMenuItem(viewMenu, ActionManager.getActionInstance(ToggleHiddenFilesAction.Descriptor.ACTION_ID, mainFrame), menuItemMnemonicHelper);
toggleTreeItem = MenuToolkit.addCheckBoxMenuItem(viewMenu, ActionManager.getActionInstance(ToggleTreeAction.Descriptor.ACTION_ID, mainFrame), menuItemMnemonicHelper);
toggleSinglePanel = MenuToolkit.addCheckBoxMenuItem(viewMenu, ActionManager.getActionInstance(ToggleSinglePanelAction.Descriptor.ACTION_ID, mainFrame), menuItemMnemonicHelper);
Expand Down Expand Up @@ -464,7 +466,10 @@ public void menuSelected(MenuEvent e) {
// Select the 'sort by' criterion currently in use in the active table
sortByItems[activeTable.getSortInfo().getCriterion().ordinal()].setSelected(true);

toggleShowFoldersFirstItem.setSelected(activeTable.getSortInfo().getFoldersFirst());
Boolean foldersFirst = activeTable.getSortInfo().getFoldersFirst();
toggleShowFoldersFirstItem.setSelected(foldersFirst);
toggleFoldersAlwaysAlphabeticalItem.setEnabled(foldersFirst);
toggleFoldersAlwaysAlphabeticalItem.setSelected(foldersFirst && activeTable.getSortInfo().getFoldersAlwaysAlphabetical());
toggleShowHiddenFilesItem.setSelected(MuConfigurations.getPreferences().getVariable(MuPreference.SHOW_HIDDEN_FILES, MuPreferences.DEFAULT_SHOW_HIDDEN_FILES));
toggleTreeItem.setSelected(activeTable.getFolderPanel().isTreeVisible());
toggleToggleAutoSizeItem.setSelected(mainFrame.isAutoSizeColumnsEnabled());
Expand Down
31 changes: 24 additions & 7 deletions src/main/com/mucommander/ui/main/table/FileTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -692,12 +692,10 @@ public void setAutoSizeColumnsEnabled(boolean enabled) {
}
}



/**
* Controls whether folders are displayed first in this FileTable or mixed with regular files.
* After calling this method, the table is refreshed to reflect the change.
*
*
* @param enabled if true, folders are displayed before regular files. If false, files are mixed with directories.
*/
public void setFoldersFirst(boolean enabled) {
Expand All @@ -707,6 +705,20 @@ public void setFoldersFirst(boolean enabled) {
}
}

/**
* Controls whether folders are sorted always alphabetical (if displayed first in this FileTable)
* After calling this method, the table is refreshed to reflect the change.
*
* @param enabled if true, folders are sorted alphabetical
*/
public void setFoldersAlwaysAlphabetical(boolean enabled) {
if (sortInfo.getFoldersAlwaysAlphabetical() != enabled) {
sortInfo.setFoldersAlwaysAlphabetical(enabled);
sortTable();
}
}


/**
* Controls whether quick search matches are displayed first in this FileTable or mixed with other files.
* @param enabled
Expand Down Expand Up @@ -926,13 +938,18 @@ public int getPageRowIncrement() {
* @param ascending true for ascending order, false for descending order
* @param foldersFirst if true, folders are displayed before regular files. If false, files are mixed with directories.
*/
private void sortBy(Column criterion, boolean ascending, boolean foldersFirst) {
private void sortBy(Column criterion, boolean ascending, boolean foldersFirst, boolean foldersAlwaysAlphabetical) {
// If we're not changing the current sort values, abort.
if (criterion == sortInfo.getCriterion() && ascending == sortInfo.getAscendingOrder() && foldersFirst == sortInfo.getFoldersFirst()) {
if (criterion == sortInfo.getCriterion()
&& ascending == sortInfo.getAscendingOrder()
&& foldersFirst == sortInfo.getFoldersFirst()
&& foldersAlwaysAlphabetical == sortInfo.getFoldersAlwaysAlphabetical()
) {
return;
}

sortInfo.setFoldersFirst(foldersFirst);
sortInfo.setFoldersAlwaysAlphabetical(foldersAlwaysAlphabetical);

// Ignore the sort criterion and order if the corresponding column is not visible
if (isColumnVisible(criterion)) {
Expand All @@ -958,7 +975,7 @@ private void sortBy(Column criterion, boolean ascending, boolean foldersFirst) {
* @param sortInfo the information to use to sort this table.
*/
public void sortBy(SortInfo sortInfo) {
sortBy(sortInfo.getCriterion(), sortInfo.getAscendingOrder(), sortInfo.getFoldersFirst());
sortBy(sortInfo.getCriterion(), sortInfo.getAscendingOrder(), sortInfo.getFoldersFirst(), sortInfo.getFoldersAlwaysAlphabetical());
}


Expand All @@ -970,7 +987,7 @@ public void sortBy(SortInfo sortInfo) {
* @param ascending true for ascending order, false for descending order
*/
public void sortBy(Column criterion, boolean ascending) {
sortBy(criterion, ascending, sortInfo.getFoldersFirst());
sortBy(criterion, ascending, sortInfo.getFoldersFirst(), sortInfo.getFoldersAlwaysAlphabetical());
}

/**
Expand Down
27 changes: 24 additions & 3 deletions src/main/com/mucommander/ui/main/table/SortInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class SortInfo implements Cloneable {
/** Should folders be displayed first, or mixed with regular files */
private boolean showFoldersFirst = MuConfigurations.getPreferences().getVariable(MuPreference.SHOW_FOLDERS_FIRST, MuPreferences.DEFAULT_SHOW_FOLDERS_FIRST);

/** Should Folders also get sorted or alway alphabetical ... only possible if Folders First enabled */
private boolean foldersAlwaysAlphabetical = MuConfigurations.getPreferences().getVariable(MuPreference.FOLDERS_ALWAYS_ALPHABETICAL, MuPreferences.DEFAULT_FOLDERS_ALWAYS_ALPHABETICAL);

private boolean showQuickSearchMatchesFirst = MuConfigurations.getPreferences().getVariable(MuPreference.SHOW_QUICK_SEARCH_MATCHES_FIRST, MuPreferences.DEFAULT_SHOW_QUICK_SEARCH_MATCHES_FIRST);

SortInfo() {
Expand Down Expand Up @@ -93,6 +96,15 @@ public void setFoldersFirst(boolean showFoldersFirst) {
this.showFoldersFirst = showFoldersFirst;
}

/**
* Sets whether folders are currently sorted always alphabetical.
*
* @param foldersAlwaysAlphabetical true if folders are sorted always alphabetical
*/
public void setFoldersAlwaysAlphabetical(boolean foldersAlwaysAlphabetical) {
this.foldersAlwaysAlphabetical = foldersAlwaysAlphabetical;
}

/**
* Returns <code>true</code> if folders are sorted and displayed before regular files, <code>false</code> if they
* are mixed with regular files and sorted altogether.
Expand All @@ -103,13 +115,22 @@ public boolean getFoldersFirst() {
return showFoldersFirst;
}

/**
* Returns <code>true</code> if folders are sorted always alphabetical
*
* @return true if folders are sorted always alphabetical
*/
public boolean getFoldersAlwaysAlphabetical() {
return foldersAlwaysAlphabetical;
}

/**
* Sets whether matched files are currently sorted and displayed before other files or mixed with them on quick search.
*
* @param showFoldersFirst true if matched are sorted and displayed before other files, false if they are mixed with regular files and sorted altogether
* @param quickSearchMatchesFirst true if matched are sorted and displayed before other files, false if they are mixed with regular files and sorted altogether
*/
void setQuickSearchMatchesFirst(boolean showFoldersFirst) {
this.showQuickSearchMatchesFirst = showFoldersFirst;
void setQuickSearchMatchesFirst(boolean quickSearchMatchesFirst) {
this.showQuickSearchMatchesFirst = quickSearchMatchesFirst;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ public synchronized void sortRows() {
private FileComparator createFileComparator(SortInfo sortInfo) {
QuickSearch qs = quickSearch != null && quickSearch.isActive() && sortInfo.getQuickSearchMatchesFirst() ? quickSearch : null;
return new FileComparator(sortInfo.getCriterion().getFileComparatorCriterion(), sortInfo.getAscendingOrder(),
sortInfo.getFoldersFirst(), qs);
sortInfo.getFoldersFirst(), sortInfo.getFoldersAlwaysAlphabetical(), qs);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public FoldersTreePanel(FolderPanel folderPanel) {
new ConfigurableFolderFilter()
);

FileComparator sort = new FileComparator(FileComparator.NAME_CRITERION, true, true);
FileComparator sort = new FileComparator(FileComparator.NAME_CRITERION, true, true, false);
model = new FilesTreeModel(treeFileFilter, sort);
tree = new JTree(model);
tree.setFont(ThemeCache.tableFont);
Expand Down
Loading