eclipse-platform / eclipse.platform.ui

Eclipse Platform
https://projects.eclipse.org/projects/eclipse.platform
Eclipse Public License 2.0
79 stars 168 forks source link

Project Explorer: automatically expand nested folders #1063

Open Wittmaxi opened 1 year ago

Wittmaxi commented 1 year ago

In the project explorer and similar treeviews, when expanding a folder that contains a singular folder, I expect that folder to recursively expand as well.

Examples

In these cases, I expect all folders to open recursively

com.wittmaxi.plugin
 └─src
    └─org.foo.com
       └─Bar.java
com.wittmaxi.plugin
 └─src
    ├─org.foo.com
    │  └─Bar.java
    └─org.baz.com (empty)

In Eclipse

grafik (click on src) grafik (click on com.vogella.contribute.parts) grafik

In IntelliJ

grafik (click on src) grafik

Note: eclipse shows a lot of these nested folders in form of "packages"

Implementation

It makes sense to implement this feature as an option in the SWT-Treeview-Widget, which would allow even more views to benefit from this behaviour.

I am ready to create a PR that implements this feature and currently looking for feedback on my proposal.

HeikoKlare commented 1 year ago

I would appreciate providing the proposed behavior. It could make sense to (optionally) provide this for all kinds of (SWT) trees but it is of course particularly useful for views visualizing folder structures, such as in the project or package explorer.

First, some investigation where the functionality needs to be placed should be conducted. At least on Windows, TreeItem.setExpanded() does only seem to be called from specific operations, such as double-clicking a node or using "expand all". Only clicking the "expand marker" next to a node does not invoke that method. I did not find any other method in TreeItem handling expand events, so maybe the "simple expand functionality" is provided by the operation system's control. In that case, OS events conducting the expand operation would have to be perceived and processed accordingly. Another option would be to only provide the specific expand behavior for actions that are provided by the Java-implemented functionality, such as double clicking the tree node. However, this could be confusing if it leads to different expand behavior depending on the way the expand action is triggered.

It would be great to receive further feedback whether providing such expand behavior for tree items would be appreciated, so that an implementation proposal by @Wittmaxi has the chance to be accepted.

HeikoKlare commented 1 year ago

One addition in context of this issue but rather nice to know: the Windows tree widget has a functionality to expand all sub folders when pressing the "*" button on the numpad. This also works in SWT trees accordingly. Please do not try on a project in the package explorer. That will take quite a while ;-)

laeubi commented 1 year ago

@HeikoKlare please be aware that for lazy providers it can be a costly operation to determine not only that there are children but that there is only one. So be careful before implementing such thing as default.

Beside that ITreeViewerListener on JFace provides a mean to listent to expanded items in a tree wich maps to org.eclipse.jface.viewers.AbstractTreeViewer.fireTreeExpanded(TreeExpansionEvent) what is triggered by the SWT org.eclipse.swt.events.TreeEvent.

So one solution would be to write a ITreeViewerListener thats check if the just expanded node has only one children and then this can be enabled selectively, this will maybe require some special handling for hidden/filtered items as well...

HeikoKlare commented 1 year ago

@laeubi Thanks for the pointers and the feedback! I missed the already provided TreeEvents/TreeExpansionEvents of SWT/JFace. Processing them seems to be a proper way to achieve the proposed behavior.

I would actually be in favor of having such an "auto-expand" functionality as an option for, e.g., the JFace TreeViewer, and not as default behavior. Every user of the viewer can then decide whether they want to enable that functionality. This is reasonable from both the performance viewpoint mentioned by you as well as the adopter's expectation not to have changes in default behavior of such central controls.

One criterion for the decision whether to use such an auto-expand functionality could be the effort for the used content provider to identify the number of children, as you mentioned with respect to lazy providers. On the other hand, as soon as you expand a node, you need to process the childs anyway, no matter whether it is only one or multiple. But in case you have a deep hierarchy with each level only containing one element, the calculation effort can become quite high. To avoid that, there could be a depth limit restricing the number of levels to expand automatically. This is, for example, also implemented in VisualVM where auto-expansion stops after a defined amount of levels as your call hierarchies can become quite large.

laeubi commented 1 year ago

Lazy Trees have a special feature where you can set hasChildren then the tree shows the handle but does not require any children. If the user expands the node these children are computed (and the handle vanishes if there are in fact none).

One usecase would be browsing a network device:

But of course you can think of others as well, e.g query a database and so on so auto-expansion could be very useful for some, but might be undesired on others, so en option of TreeViewer#setAutoExpandToLevel(...) seems a good choice.

HeikoKlare commented 1 year ago

That's an interesting scenario. Great to have that documented here.

In addition to having such an auto-expand functionality activated optionally, it might also be useful to ensure reponsiveness of the viewer in case it is activated by making the auto-expansion track the elapsed time and deal with long-running expansion to avoid an unresponsive UI. There might be two (or more) options:

  1. Abort the expansion before reaching the defined depth in case it takes too long. This could be problematic from a user experience perspective, as you may not understand why a different amount of levels expands in different (or even the same) scenarios.
  2. Show a cancellable progress when the operation takes too long, so the user can decide whether they want to wait for auto expansion. W.r.t. to this option, I saw some discussion in another issue or PR about progress dialogs that open only when the progress takes more than a defined amount of time to not disturb the user with progress dialogs for fast finishing operations. I can't find that one again right now, but in case this option will be implemented it would be worth to look for it again.

One nitpicky addition regarding a potential API extension for an auto-expand functionality of a TreeViewer: The name should probably cover that the intended functionality is not a general auto-expansion but only applies to cases where a single element is contained, such as: TreeViewer#setAutoExpandOnSingleChild(int numberOfLevelsToExpand)

iloveeclipse commented 3 months ago

Is this delivered in 4.32? If so, please close, if not, please give a hint why it is still open.

Wittmaxi commented 3 months ago

@iloveeclipse Yes, this can be closed!

HeikoKlare commented 2 months ago

Reopening as the contributions for this issue had to be reverted temporarily (until the functionality itself is improved) in #2123.