From f3d65d6d74de84ae2a41c6f5ca86e11789b25b78 Mon Sep 17 00:00:00 2001 From: Sergei Tachenov Date: Wed, 10 May 2023 11:52:42 +0300 Subject: [PATCH] IDEA-74443 Implement Sort by Time in Project View GitOrigin-RevId: 30511cc19142b341a3d135f99320a01a2bd36830 --- .../testData/projectView/sortByTime/a.java | 0 .../testData/projectView/sortByTime/a.txt | 0 .../testData/projectView/sortByTime/b.java | 0 .../testData/projectView/sortByTime/b.txt | 0 .../projectView/ProjectTreeSortingTest.java | 41 +++++++++++++++++++ .../ide/projectView/NodeSortSettings.kt | 1 + .../ide/projectView/ProjectViewNode.java | 5 +++ .../intellij/ide/projectView/ProjectView.java | 8 ++++ .../ide/projectView/ProjectViewSettings.java | 10 +++++ .../impl/AbstractProjectViewPane.java | 5 +++ .../impl/GroupByTypeComparator.java | 27 ++++++++---- .../impl/ProjectTreeStructure.java | 5 +++ .../ide/projectView/impl/ProjectViewImpl.java | 38 +++++++++++++++++ .../ProjectViewInplaceCommentProducerImpl.kt | 11 +---- .../impl/ProjectViewSharedSettings.kt | 1 + .../ide/projectView/impl/ProjectViewState.kt | 2 + .../impl/nodes/AbstractPsiBasedNode.java | 17 ++++++++ .../ide/projectView/impl/projectViewUtil.kt | 13 ++++++ .../src/messages/ActionsBundle.properties | 2 + .../src/idea/LangActions.xml | 2 + .../projectView/TestProjectTreeStructure.java | 10 +++++ 21 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 java/java-tests/testData/projectView/sortByTime/a.java create mode 100644 java/java-tests/testData/projectView/sortByTime/a.txt create mode 100644 java/java-tests/testData/projectView/sortByTime/b.java create mode 100644 java/java-tests/testData/projectView/sortByTime/b.txt diff --git a/java/java-tests/testData/projectView/sortByTime/a.java b/java/java-tests/testData/projectView/sortByTime/a.java new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/projectView/sortByTime/a.txt b/java/java-tests/testData/projectView/sortByTime/a.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/projectView/sortByTime/b.java b/java/java-tests/testData/projectView/sortByTime/b.java new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/projectView/sortByTime/b.txt b/java/java-tests/testData/projectView/sortByTime/b.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java index 46530255791f..fc0ee0550f3e 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java @@ -15,6 +15,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.tree.TreePath; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.attribute.FileTime; +import java.time.LocalDateTime; +import java.time.Month; +import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; @@ -94,6 +100,41 @@ public class ProjectTreeSortingTest extends BaseProjectViewTestCase { """); } + public void testSortByTime() { + setModificationTime("a.java", LocalDateTime.of(2023, Month.MAY, 8, 0, 0)); + setModificationTime("a.txt", LocalDateTime.of(2023, Month.MAY, 8, 0, 1)); + setModificationTime("b.java", LocalDateTime.of(2023, Month.MAY, 7, 0, 1)); + setModificationTime("b.txt", LocalDateTime.of(2023, Month.MAY, 7, 0, 0)); + myProjectView.setSortByTime(myPane.getId(), false); + myStructure.setSortByTime(false); + assertTree(""" + -sortByTime + a.java + a.txt + b.java + b.txt + """); + + myProjectView.setSortByTime(myPane.getId(), true); + myStructure.setSortByTime(true); + assertTree(""" + -sortByTime + b.txt + b.java + a.java + a.txt + """); + } + + private void setModificationTime(String fileName, LocalDateTime time) { + try { + Files.setLastModifiedTime(getContentRoot().toNioPath().resolve(fileName), FileTime.from(time.toInstant(ZoneOffset.UTC))); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + public void testFoldersOnTop() { // first, check with 'sort by type' disabled myProjectView.setSortByType(myPane.getId(), false); diff --git a/platform/lang-api/src/com/intellij/ide/projectView/NodeSortSettings.kt b/platform/lang-api/src/com/intellij/ide/projectView/NodeSortSettings.kt index a8f3555b0de2..ba0763bf9ac2 100644 --- a/platform/lang-api/src/com/intellij/ide/projectView/NodeSortSettings.kt +++ b/platform/lang-api/src/com/intellij/ide/projectView/NodeSortSettings.kt @@ -8,4 +8,5 @@ data class NodeSortSettings( val isManualOrder: Boolean, val isFoldersAlwaysOnTop: Boolean, val isSortByType: Boolean, + val isSortByTime: Boolean, ) diff --git a/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java b/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java index d2f21b5c4b15..0002f085e91e 100644 --- a/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java +++ b/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java @@ -255,6 +255,11 @@ public abstract class ProjectViewNode extends AbstractTreeNode im return null; } + @Nullable + public Comparable getTimeSortKey() { + return null; + } + public boolean shouldDrillDownOnEmptyElement() { return false; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java index 54d5c2fb8bba..7d45cdf9bcc3 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java @@ -144,8 +144,16 @@ public abstract class ProjectView { public abstract void setManualOrder(@NotNull String paneId, boolean enabled); public abstract boolean isSortByType(String paneId); + public abstract void setSortByType(@NotNull String paneId, final boolean sortByType); + public boolean isSortByTime(String paneId) { + return false; + } + + public void setSortByTime(@NotNull String paneId, final boolean sortByTime) { + } + public abstract AbstractProjectViewPane getCurrentProjectViewPane(); @NotNull diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java index 540b5f1b892b..27624cba9e1c 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java @@ -15,6 +15,10 @@ public interface ProjectViewSettings extends ViewSettings { return false; } + default boolean isSortByTime() { + return false; + } + /** * If {@code true} then {@link com.intellij.ide.projectView.impl.NestingTreeStructureProvider} will modify the tree presentation * according to the rules managed by {@link com.intellij.ide.projectView.impl.ProjectViewFileNestingService}: some peer files will be @@ -111,6 +115,12 @@ public interface ProjectViewSettings extends ViewSettings { return view != null && view.isFoldersAlwaysOnTop(getPaneID(view)); } + @Override + public boolean isSortByTime() { + ProjectView view = getProjectView(); + return view != null && view.isSortByTime(getPaneID(view)); + } + @Override public boolean isShowMembers() { ProjectView view = getProjectView(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java index 9d33ad0cffd1..aab80fe8f013 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java @@ -1024,6 +1024,11 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl return true; } + @ApiStatus.Internal + public boolean supportsSortByTime() { + return true; + } + @NotNull private static Color getFileForegroundColor(@NotNull Project project, @NotNull VirtualFile file) { FileEditorManager manager = FileEditorManager.getInstance(project); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/GroupByTypeComparator.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/GroupByTypeComparator.java index 3ed473ab8c5e..07d454db6674 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/GroupByTypeComparator.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/GroupByTypeComparator.java @@ -1,9 +1,9 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.projectView.impl; +import com.intellij.ide.projectView.NodeSortSettings; import com.intellij.ide.projectView.ProjectView; import com.intellij.ide.projectView.ProjectViewNode; -import com.intellij.ide.projectView.NodeSortSettings; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.AlphaComparator; import com.intellij.ide.util.treeView.NodeDescriptor; @@ -49,7 +49,7 @@ public class GroupByTypeComparator implements Comparator> { if (descriptor1 instanceof ProjectViewNode node1 && descriptor2 instanceof ProjectViewNode node2) { - NodeSortSettings settings = new NodeSortSettings(isManualOrder(), isFoldersAlwaysOnTop(), isSortByType()); + NodeSortSettings settings = new NodeSortSettings(isManualOrder(), isFoldersAlwaysOnTop(), isSortByType(), isSortByTime()); int sortResult = node1.getSortOrder(settings).compareTo(node2.getSortOrder(settings)); if (sortResult != 0) return sortResult; @@ -74,15 +74,21 @@ public class GroupByTypeComparator implements Comparator> { } } - if (settings.isSortByType()) { - final Comparable typeSortKey1 = node1.getTypeSortKey(); - final Comparable typeSortKey2 = node2.getTypeSortKey(); + if (settings.isSortByTime()) { + final Comparable timeSortKey1 = node1.getTimeSortKey(); + final Comparable timeSortKey2 = node2.getTimeSortKey(); + int result = compare(timeSortKey1, timeSortKey2); + if (result != 0) return result; + } + else if (settings.isSortByType()) { + final Comparable typeSortKey1 = node1.getTypeSortKey(); + final Comparable typeSortKey2 = node2.getTypeSortKey(); int result = compare(typeSortKey1, typeSortKey2); if (result != 0) return result; } else { - final Comparable typeSortKey1 = node1.getSortKey(); - final Comparable typeSortKey2 = node2.getSortKey(); + final Comparable typeSortKey1 = node1.getSortKey(); + final Comparable typeSortKey2 = node2.getSortKey(); if (typeSortKey1 != null && typeSortKey2 != null) { int result = compare(typeSortKey1, typeSortKey2); if (result != 0) return result; @@ -116,6 +122,13 @@ public class GroupByTypeComparator implements Comparator> { return ProjectView.getInstance(project).isSortByType(myPaneId); } + protected boolean isSortByTime() { + if (project == null) { + return false; + } + return ProjectView.getInstance(project).isSortByTime(myPaneId); + } + protected boolean isAbbreviateQualifiedNames() { return project != null && ProjectView.getInstance(project).isAbbreviatePackageNames(myPaneId); } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectTreeStructure.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectTreeStructure.java index 832e6cb9c1b2..63cf917984e5 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectTreeStructure.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectTreeStructure.java @@ -70,4 +70,9 @@ public abstract class ProjectTreeStructure extends AbstractProjectTreeStructure return ProjectView.getInstance(myProject).isShowVisibilityIcons(myId); } + @Override + public boolean isSortByTime() { + return ProjectView.getInstance(myProject).isSortByTime(myId); + } + } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 8db4c78e218f..239f8cc9f41a 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -516,6 +516,28 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo } }; + private final Option mySortByTime = new Option() { + @Override + public boolean isEnabled(@NotNull AbstractProjectViewPane pane) { + return pane.supportsSortByTime(); + } + + @Override + public boolean isSelected() { + return myCurrentState.getSortByTime(); + } + + @Override + public void setSelected(boolean selected) { + if (myProject.isDisposed()) return; + boolean updated = selected != isSelected(); + myCurrentState.setSortByTime(selected); + getDefaultState().setSortByTime(selected); + getGlobalOptions().setSortByTime(selected); + if (updated) updatePanes(true); + } + }; + private String myCurrentViewId; private String myCurrentViewSubId; // - options @@ -1824,11 +1846,21 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo return mySortByType.isSelected() && mySortByType.isEnabled(paneId); } + @Override + public boolean isSortByTime(String paneId) { + return mySortByTime.isSelected() && mySortByTime.isEnabled(paneId); + } + @Override public void setSortByType(@NotNull String paneId, final boolean sortByType) { if (mySortByType.isEnabled(paneId)) mySortByType.setSelected(sortByType); } + @Override + public void setSortByTime(@NotNull String paneId, boolean sortByTime) { + if (mySortByTime.isEnabled(paneId)) mySortByTime.setSelected(sortByTime); + } + boolean isSelectOpenedFileEnabled() { return !isAutoscrollFromSourceEnabled(myCurrentViewId) || AdvancedSettings.getBoolean("project.view.do.not.autoscroll.to.libraries"); } @@ -2019,6 +2051,12 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo super(view -> view.mySortByType); } } + + static final class SortByTime extends Action { + SortByTime() { + super(view -> view.mySortByTime); + } + } } private static final class ProjectViewPaneChangesCollector extends CounterUsagesCollector { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewInplaceCommentProducerImpl.kt b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewInplaceCommentProducerImpl.kt index f9456598c884..c5676bb93f2a 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewInplaceCommentProducerImpl.kt +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewInplaceCommentProducerImpl.kt @@ -13,8 +13,6 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiFileSystemItem import com.intellij.ui.SimpleTextAttributes import com.intellij.util.text.JBDateFormat -import java.nio.file.Files -import java.nio.file.attribute.BasicFileAttributes internal fun appendInplaceComments(node: ProjectViewNode<*>, appender: InplaceCommentAppender) { val parentNode = node.parent @@ -26,14 +24,7 @@ internal fun appendInplaceComments(node: ProjectViewNode<*>, appender: InplaceCo // To be used in Rider once it migrates from legacy logic, don't change the signature and/or visibility. fun appendInplaceComments(appender: InplaceCommentAppender, project: Project?, file: VirtualFile?) { - val ioFile = if (file == null || file.isDirectory || !file.isInLocalFileSystem) null else file.toNioPath() - val fileAttributes = try { - if (ioFile == null) null else Files.readAttributes(ioFile, BasicFileAttributes::class.java) - } - catch (ignored: Exception) { - null - } - + val fileAttributes = getFileAttributes(file) if (fileAttributes != null) { appender.append(" ", SimpleTextAttributes.REGULAR_ATTRIBUTES) val attributes = SimpleTextAttributes.GRAYED_SMALL_ATTRIBUTES diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewSharedSettings.kt b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewSharedSettings.kt index 7b269f5ff577..a154ce2fc69c 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewSharedSettings.kt +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewSharedSettings.kt @@ -16,6 +16,7 @@ class ProjectViewSharedSettings : PersistentStateComponent { var showURL = ProjectViewSettings.Immutable.DEFAULT.isShowURL var showVisibilityIcons = ProjectViewSettings.Immutable.DEFAULT.isShowVisibilityIcons var sortByType = false + var sortByTime = false var useFileNestingRules = ProjectViewSettings.Immutable.DEFAULT.isUseFileNestingRules override fun noStateLoaded() { @@ -62,6 +63,7 @@ class ProjectViewState : PersistentStateComponent { showURL = Registry.`is`("project.tree.structure.show.url") showVisibilityIcons = ProjectViewSharedSettings.instance.showVisibilityIcons sortByType = ProjectViewSharedSettings.instance.sortByType + sortByTime = ProjectViewSharedSettings.instance.sortByTime } override fun loadState(state: ProjectViewState) { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractPsiBasedNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractPsiBasedNode.java index 2fd2ca85ff56..30747a96e6d2 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractPsiBasedNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractPsiBasedNode.java @@ -49,6 +49,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Objects; +import static com.intellij.ide.projectView.impl.ProjectViewUtilKt.getFileAttributes; import static com.intellij.ide.util.treeView.NodeRenderer.getSimpleTextAttributes; /** @@ -58,6 +59,7 @@ import static com.intellij.ide.util.treeView.NodeRenderer.getSimpleTextAttribute */ public abstract class AbstractPsiBasedNode extends ProjectViewNode implements ValidateableNode, StatePreservingNavigatable { private static final Logger LOG = Logger.getInstance(AbstractPsiBasedNode.class.getName()); + private volatile long timestamp; protected AbstractPsiBasedNode(final Project project, @NotNull Value value, @@ -139,6 +141,11 @@ public abstract class AbstractPsiBasedNode extends ProjectViewNode return PsiUtilCore.getVirtualFile(psiElement); } + @Override + public @Nullable Comparable getTimeSortKey() { + return timestamp == 0 ? null : timestamp; + } + @Override protected void appendInplaceComments(@NotNull InplaceCommentAppender appender) { if (UISettings.getInstance().getShowInplaceComments()) { @@ -204,9 +211,19 @@ public abstract class AbstractPsiBasedNode extends ProjectViewNode updateImpl(data); data.setIcon(patchIcon(myProject, data.getIcon(true), getVirtualFile())); CompoundProjectViewNodeDecorator.get(myProject).decorate(this, data); + updateTimestamp(); }); } + private void updateTimestamp() { + if (getSettings() instanceof ProjectViewSettings projectViewSettings && !projectViewSettings.isSortByTime()) { + timestamp = 0; // skip for performance reasons + return; + } + var attributes = getFileAttributes(getVirtualFile()); + timestamp = attributes == null ? 0 : attributes.lastModifiedTime().toMillis(); + } + @Iconable.IconFlags protected int getIconableFlags() { int flags = 0; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/projectViewUtil.kt b/platform/lang-impl/src/com/intellij/ide/projectView/impl/projectViewUtil.kt index 53577eef4591..c17d24f73dd7 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/projectViewUtil.kt +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/projectViewUtil.kt @@ -17,6 +17,8 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiDirectory import com.intellij.util.SmartList import org.jetbrains.annotations.ApiStatus +import java.nio.file.Files +import java.nio.file.attribute.BasicFileAttributes internal fun getNodeElement(userObject: Any?): Any? { return when (userObject) { @@ -108,3 +110,14 @@ fun getSelectedLibrary(userObjectsPath: Array?): LibraryOrderEntry? { ?: return null return ModuleRootManager.getInstance(module).fileIndex.getOrderEntryForFile(directory.virtualFile) as? LibraryOrderEntry } + +internal fun getFileAttributes(file: VirtualFile?): BasicFileAttributes? { + val ioFile = if (file == null || file.isDirectory || !file.isInLocalFileSystem) null else file.toNioPath() + val fileAttributes = try { + if (ioFile == null) null else Files.readAttributes(ioFile, BasicFileAttributes::class.java) + } + catch (ignored: Exception) { + null + } + return fileAttributes +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 15a60a614ed4..bf4e192d5a63 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -1471,6 +1471,8 @@ action.ProjectView.ShowVisibilityIcons.text=Show Visibility Icons action.ProjectView.ShowVisibilityIcons.description=Show icon of element visibility before its name action.ProjectView.SortByType.text=Sort by Type action.ProjectView.SortByType.description=Sort files of different types separately +action.ProjectView.SortByTime.text=Sort by Modification Time +action.ProjectView.SortByTime.description=Sort files of by their last modification time action.ScopeView.EditScopes.text=Ed_it Scopes... action.ScopeView.EditScopes.description=Edit Scopes... action.ProjectView.FileNesting.text=File Nesting... diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index bb5b089bd4e6..dd75f779568d 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -927,6 +927,8 @@ + diff --git a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java index 62a67f813cd8..3ee41d758c7b 100644 --- a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java +++ b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java @@ -20,6 +20,7 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple protected boolean myHideEmptyMiddlePackages; protected boolean myFlattenPackages; private boolean myFlattenModules; + private boolean mySortByTime; protected boolean myShowLibraryContents = true; public TestProjectTreeStructure(@NotNull Project project, Disposable parentDisposable) { @@ -80,6 +81,15 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple myFlattenModules = flattenModules; } + @Override + public boolean isSortByTime() { + return mySortByTime; + } + + public void setSortByTime(boolean sortByTime) { + mySortByTime = sortByTime; + } + public void setHideEmptyMiddlePackages(boolean hideEmptyMiddlePackages) { myHideEmptyMiddlePackages = hideEmptyMiddlePackages; }