/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.nextreports.designer.util; import java.util.ArrayList; import java.util.Enumeration; import javax.swing.JTree; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import ro.nextreports.designer.Globals; import ro.nextreports.designer.StructurePanel; import ro.nextreports.designer.StructureTreeNode; import ro.nextreports.designer.datasource.DefaultDataSourceManager; import ro.nextreports.designer.querybuilder.DBBrowserNode; import ro.nextreports.designer.querybuilder.DBBrowserTree; import ro.nextreports.designer.querybuilder.DBObject; import ro.nextreports.designer.querybuilder.tree.DBNodeExpander; /** * @author Decebal Suiu */ public class TreeUtil { /** * Expand all nodes of a tree. * * @param tree The tree whose nodes to expand. */ public static void expandAll(JTree tree) { expandAll(tree, new TreePath(tree.getModel().getRoot())); } /** * Collapse all nodes of a tree. * * @param tree The tree whose nodes to expand. */ public static void collapseAll(JTree tree) { TreePath pathToRoot = new TreePath(tree.getModel().getRoot()); collapseAll(tree, pathToRoot); if (!tree.isRootVisible()) { tree.expandPath(pathToRoot); } } public static void collapseAllFromNode(JTree tree, DBBrowserNode node) { TreePath pathToNode = new TreePath(node); collapseAll(tree, pathToNode); if (!tree.isRootVisible()) { tree.expandPath(pathToNode); } } /** * Expand a tree node and all its child nodes recursively. * * @param tree The tree whose nodes to expand. * @param path Path to the node to start at. */ public static void expandAll(JTree tree, TreePath path) { Object node = path.getLastPathComponent(); TreeModel model = tree.getModel(); if (model.isLeaf(node)) { return; } tree.expandPath(path); int num = model.getChildCount(node); for (int i = 0; i < num; i++) { expandAll(tree, path.pathByAddingChild(model.getChild(node, i))); } } /** * Collapse a tree node and all its child nodes recursively. * * @param tree The tree whose nodes to collapse. * @param path Path to the node to start at. */ public static void collapseAll(JTree tree, TreePath path) { Object node = path.getLastPathComponent(); TreeModel model = tree.getModel(); if (model.isLeaf(node)) { return; } int num = model.getChildCount(node); for (int i = 0; i < num; i++) { collapseAll(tree, path.pathByAddingChild(model.getChild(node, i))); } tree.collapsePath(path); } /** * Get a copy of the list of expanded tree paths of a tree. */ public static TreePath[] getExpandedPaths(JTree tree) { ArrayList<TreePath> expandedPaths = new ArrayList<TreePath>(); TreePath rootPath = new TreePath(tree.getModel().getRoot()); Enumeration enumeration = tree.getExpandedDescendants(rootPath); if (enumeration != null) { while (enumeration.hasMoreElements()) { expandedPaths.add((TreePath)enumeration.nextElement()); } } TreePath[] array = new TreePath[expandedPaths.size()]; expandedPaths.toArray(array); return array; } /** * Expand all the previously remembered expanded paths. */ public static void setExpandedPaths(JTree tree, TreePath[] expandedPaths) { if (expandedPaths == null) { return; } for (int i = 0; i < expandedPaths.length; ++i) { TreePath oldPath = expandedPaths[i]; TreePath newPath = searchPath(tree.getModel(), oldPath); if (newPath != null) { tree.expandPath(newPath); } } } /** * Search for a path in the specified tree model, whose nodes have * the same name (compared using <code>equals()</code>) * as the ones specified in the old path. * * @return a new path for the specified model, or null if no such path * could be found. */ public static TreePath searchPath(TreeModel model, TreePath oldPath) { Object treenode = model.getRoot(); Object[] oldPathNodes = oldPath.getPath(); TreePath newPath = new TreePath(treenode); for (int i = 0; i < oldPathNodes.length; ++i) { Object oldPathNode = oldPathNodes[i]; if (treenode.toString().equals(oldPathNode.toString())) { if (i == (oldPathNodes.length - 1)) { return newPath; } else { if (model.isLeaf(treenode)) { return null; // not found } else { int count = model.getChildCount(treenode); boolean foundChild = false; for (int j = 0; j < count; ++j) { Object child = model.getChild(treenode, j); if (child.toString().equals(oldPathNodes[i + 1].toString())) { newPath = newPath.pathByAddingChild(child); treenode = child; foundChild = true; break; } } if (!foundChild) { return null; // couldn't find child with same name } } } } } return null; } public static void refreshCharts() throws Exception { refresh(DBNodeExpander.CHARTS); } public static void refreshReports() throws Exception { refresh(DBNodeExpander.REPORTS); } public static void refreshQueries() throws Exception { refresh(DBNodeExpander.QUERIES); } private static void refresh(String nodeExpander) throws Exception { DBBrowserTree tree = Globals.getMainFrame().getQueryBuilderPanel().getTree(); final DBBrowserNode selectedNode = (DBBrowserNode) tree.getLastSelectedPathComponent(); DBBrowserNode node = tree.searchNode(nodeExpander); node.removeAllChildren(); tree.startExpandingTree(node, false, null); if (selectedNode != null) { // is null for QUERIES, REPORTS and CHARTS nodes if (selectedNode.getDBObject().getAbsolutePath() != null) { tree.selectNode(selectedNode.getDBObject()); } } } public static void refreshDatabase() throws Exception { DBBrowserTree tree = Globals.getMainFrame().getQueryBuilderPanel().getTree(); DBBrowserNode node = tree.searchNode(DBNodeExpander.TABLES); // schema node was not expanded : nothing to refresh if (node == null) { return; } node.removeAllChildren(); tree.startExpandingTree(node, false, null); node = tree.searchNode(DBNodeExpander.VIEWS); node.removeAllChildren(); tree.startExpandingTree(node, false, null); node = tree.searchNode(DBNodeExpander.PROCEDURES); node.removeAllChildren(); tree.startExpandingTree(node, false, null); } public static void expandConnectedDataSource() { DBBrowserTree tree = Globals.getMainFrame().getQueryBuilderPanel().getTree(); String name = DefaultDataSourceManager.getInstance().getConnectedDataSource().getName(); DBBrowserNode node = tree.searchNode(name, DBObject.DATABASE); if (node != null) { if (node.getChildCount() == 0) { tree.startExpandingTree(node, true, null); tree.fireTreeExpanded(new TreePath(node.getPath())); for (int i = 0, size = node.getChildCount(); i < size; i++) { tree.startExpandingTree((DBBrowserNode) node.getChildAt(i), false, null); } } } } /** Get the data source node for the current node * * @param node current node * @return data source node if any for the current node or throws IllegalArgumentException for root node * */ public static DBBrowserNode getDataSourceNode(DBBrowserNode node) { byte type = node.getDBObject().getType(); if (type == DBObject.DATASOURCE) { throw new IllegalArgumentException("Invalid node type : " + type); } else if (type == DBObject.DATABASE) { return node; } else { DBBrowserNode parent = (DBBrowserNode)node.getParent(); while (parent.getDBObject().getType() != DBObject.DATABASE) { parent = (DBBrowserNode)parent.getParent(); } return parent; } } /** * Get tree path for a band element selection * @param row band element row * @param column band element column * @return tree path for a band element selection */ public static TreePath getTreePath(int row, int column) { StructurePanel structurePanel = Globals.getReportDesignerPanel().getStructurePanel(); StructureTreeNode node = structurePanel.getBandElementTreeNode(row, column); TreePath path = null; // for cell spans node can be null - see setSelectionRange in DefaultSelectionModel if (node != null) { boolean filter = Globals.getReportDesignerPanel().getStructurePanel().getStructureTreeModel().isActivatedFilter(); if ((filter && node.isVisible()) || !filter) { path = new TreePath(structurePanel.getStructureTreeModel().getPathToRoot(node)); } } return path; } /** * Get tree path for a row element selection * @param row row element * @return tree path for a row element selection */ public static TreePath getTreePath(int row) { StructurePanel structurePanel = Globals.getReportDesignerPanel().getStructurePanel(); StructureTreeNode node = structurePanel.getRowElementTreeNode(row); TreePath path = null; // for cell spans node can be null - see setSelectionRange in DefaultSelectionModel if (node != null) { boolean filter = Globals.getReportDesignerPanel().getStructurePanel().getStructureTreeModel().isActivatedFilter(); if ((filter && node.isVisible()) || !filter) { path = new TreePath(structurePanel.getStructureTreeModel().getPathToRoot(node)); } } return path; } }