package com.link_intersystems.gitdirstat.ui.treeobjects;
import java.awt.BorderLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.math.BigInteger;
import java.util.Enumeration;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import com.link_intersystems.gitdirstat.domain.TreeObject;
import com.link_intersystems.gitdirstat.domain.TreeObjectSortBy;
import com.link_intersystems.gitdirstat.ui.GitRepositoryModel;
import com.link_intersystems.gitdirstat.ui.PathModel;
import com.link_intersystems.swing.FileModel;
import com.link_intersystems.swing.FileModelAdapterFactory;
import com.link_intersystems.swing.HumanReadableFileSizeTreeCellRenderer;
import com.link_intersystems.swing.RadioButtonGroupModel;
import com.link_intersystems.swing.ShowPopupMouseAdapter;
import com.link_intersystems.util.SortOrder;
public class TreeObjectsTreeComponent extends GitRepositoryComponent {
private static final long serialVersionUID = 8588810751988085851L;
private JTree treeObjectsTree = new JTree();
private JScrollPane treeObjectsScrollPane = new JScrollPane(treeObjectsTree);
private RadioButtonGroupModel sortByButtonGroupModel;
private RadioButtonGroupModel sortOrderButtonGroupModel;
private SortingUpdateListener sortingUpdateListener;
public TreeObjectsTreeComponent() {
setLayout(new BorderLayout());
HumanReadableFileSizeTreeCellRenderer cellRenderer = new HumanReadableFileSizeTreeCellRenderer();
TreeObjectFileModelAdapterFactory modelAdapterFactory = new TreeObjectFileModelAdapterFactory();
cellRenderer.setFileModelAdapterFactory(modelAdapterFactory);
treeObjectsTree.setCellRenderer(cellRenderer);
treeObjectsTree.setRootVisible(false);
treeObjectsTree.setExpandsSelectedPaths(true);
add(treeObjectsScrollPane, BorderLayout.CENTER);
createPopupMenu();
}
@Override
public void beforeVisible() {
collapseAll(treeObjectsTree);
}
private void collapseAll(JTree tree) {
TreeNode root = (TreeNode) tree.getModel().getRoot();
int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
TreeNode childAt = root.getChildAt(i);
collapseAll(tree, new TreePath(new Object[] { root, childAt }));
}
}
@SuppressWarnings("unchecked")
private void collapseAll(JTree tree, TreePath parent) {
TreeNode node = (TreeNode) parent.getLastPathComponent();
if (node.getChildCount() >= 0) {
for (Enumeration<TreeNode> e = node.children(); e.hasMoreElements();) {
TreeNode n = e.nextElement();
TreePath path = parent.pathByAddingChild(n);
collapseAll(tree, path);
}
}
tree.collapsePath(parent);
// tree.collapsePath(parent);
}
private void createPopupMenu() {
JPopupMenu popup = new JPopupMenu();
JMenu sortMenu = new JMenu("Sorting");
popup.add(sortMenu);
sortByButtonGroupModel = createSortByMenuEntries(sortMenu);
sortMenu.addSeparator();
sortOrderButtonGroupModel = createSortOrderMenuEntries(sortMenu);
sortingUpdateListener = new SortingUpdateListener(
sortByButtonGroupModel, sortOrderButtonGroupModel);
sortByButtonGroupModel.addPropertyChangeListener("selectedValue",
sortingUpdateListener);
sortOrderButtonGroupModel.addPropertyChangeListener("selectedValue",
sortingUpdateListener);
ShowPopupMouseAdapter popupMenuMouseAdapter = new ShowPopupMouseAdapter(
popup);
treeObjectsTree.addMouseListener(popupMenuMouseAdapter);
}
private RadioButtonGroupModel createSortOrderMenuEntries(JMenu parent) {
RadioButtonGroupModel sortOrderButtonGroupModel = new RadioButtonGroupModel();
JRadioButtonMenuItem sortOrderAscSizeButton = new JRadioButtonMenuItem(
"ascending");
JRadioButtonMenuItem sortOrderDescSizeButton = new JRadioButtonMenuItem(
"descending");
sortOrderButtonGroupModel.add(sortOrderAscSizeButton, SortOrder.ASC);
sortOrderButtonGroupModel.add(sortOrderDescSizeButton, SortOrder.DESC);
sortOrderButtonGroupModel.setSelected(sortOrderDescSizeButton, true);
parent.add(sortOrderAscSizeButton);
parent.add(sortOrderDescSizeButton);
return sortOrderButtonGroupModel;
}
private RadioButtonGroupModel createSortByMenuEntries(JMenu parent) {
JRadioButtonMenuItem sortBySizeButton = new JRadioButtonMenuItem(
"by size");
JRadioButtonMenuItem sortByPathnameButton = new JRadioButtonMenuItem(
"by pathname");
RadioButtonGroupModel sortByButtonGroupModel = new RadioButtonGroupModel();
sortByButtonGroupModel.add(sortBySizeButton, TreeObjectSortBy.SIZE);
sortByButtonGroupModel.add(sortByPathnameButton, TreeObjectSortBy.NAME);
sortByButtonGroupModel.setSelected(sortBySizeButton, true);
parent.add(sortBySizeButton);
parent.add(sortByPathnameButton);
return sortByButtonGroupModel;
}
protected void updateCommitRangeTree() {
GitRepositoryModel model = getModel();
if (model != null) {
PathModel pathModel = model.getPathModel();
TreeObjectsTreeModel treeModel = pathModel.getTreeModel();
sortingUpdateListener.setTreeObjectsTreeModel(treeModel);
treeObjectsTree.setModel(treeModel);
TreeSelectionModel treeSelectionModel = pathModel
.getTreeSelectionModel();
treeObjectsTree.setSelectionModel(treeSelectionModel);
}
}
private static class SortingUpdateListener implements
PropertyChangeListener {
private RadioButtonGroupModel sortByButtonGroupModel;
private RadioButtonGroupModel sortOrderButtonGroupModel;
private TreeObjectsTreeModel treeObjectsTreeModel;
public SortingUpdateListener(
RadioButtonGroupModel sortByButtonGroupModel,
RadioButtonGroupModel sortOrderButtonGroupModel) {
this.sortByButtonGroupModel = sortByButtonGroupModel;
this.sortOrderButtonGroupModel = sortOrderButtonGroupModel;
}
public void setTreeObjectsTreeModel(
TreeObjectsTreeModel treeObjectsTreeModel) {
this.treeObjectsTreeModel = treeObjectsTreeModel;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (treeObjectsTreeModel != null) {
TreeObjectSortBy sortBy = (TreeObjectSortBy) sortByButtonGroupModel
.getSelectionValue();
SortOrder sortOrder = (SortOrder) sortOrderButtonGroupModel
.getSelectionValue();
treeObjectsTreeModel.setSorting(sortBy, sortOrder);
}
}
}
private static class TreeObjectFileModel implements FileModel {
private TreeObject treeObject;
public TreeObjectFileModel(TreeObject treeObject) {
this.treeObject = treeObject;
}
@Override
public String getName() {
return treeObject.getName();
}
@Override
public BigInteger getSize() {
return treeObject.getSize();
}
}
private static class TreeObjectFileModelAdapterFactory implements
FileModelAdapterFactory {
@Override
public FileModel createAdapter(Object treeModelObject) {
FileModel fileModel = null;
TreeObject treeObject = null;
if (treeModelObject instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode mutableTreeNode = DefaultMutableTreeNode.class
.cast(treeModelObject);
Object userObject = mutableTreeNode.getUserObject();
if (userObject instanceof TreeObject) {
treeObject = TreeObject.class.cast(userObject);
}
}
if (treeObject != null) {
fileModel = new TreeObjectFileModel(treeObject);
}
return fileModel;
}
}
}