/** * returns an array of strings of all selected targets, or null if nothing is selected * * @return array of string of targets */ private String[] getSelectedTargetsAsArray() { TreePath[] paths = this.getSelectionPaths(); if (paths == null) { return null; } String targets[] = new String[paths.length]; for (int i = 0; i < paths.length; i++) { TreePath path = paths[i]; DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent(); SVNTreeNodeData svnNode = (SVNTreeNodeData) dmtn.getUserObject(); targets[i] = (ConfigurationManager.getInstance().getConfig().getWorkingDirectory()) + svnNode.getPath(); } return targets; }
/** * returns a default mutable tree representation of a given working copy node * * @param svnTreeNode mode of an svn working copy model * @return root DefaultMutableTreeNode of the given model */ public static DefaultMutableTreeNode buildTreeNode(SVNTreeNodeData svnTreeNode) { DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(svnTreeNode); for (Iterator iterator = svnTreeNode.getChildren().iterator(); iterator.hasNext(); ) { SVNTreeNodeData svnTreeNodeData = (SVNTreeNodeData) iterator.next(); DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(); newNode.setUserObject(svnTreeNodeData); DefaultMutableTreeNode newChild = buildTreeNode(svnTreeNodeData); if (newChild != null) { rootNode.add(newChild); } } return rootNode; }
/** * recursively refreshes a given node within the tree * * @param node node at which to begin the resursive refresh * @param online indicator as to whether an online refresh should be performed */ private void refresh(final DefaultMutableTreeNode node, final boolean online) { SVNTreeNodeData nodeData = (SVNTreeNodeData) node.getUserObject(); // if a userObject doesn't exist for the given node, then just return if (nodeData == null) { return; } final String workingCopy = ConfigurationManager.getInstance().getConfig().getWorkingDirectory() + nodeData.getPath(); // since building SVNTreeModel and buildTreeNode can take some time, we'll execute them in a // separate thread // so that we can continue updating the UI in realtime. Thread t = new Thread( new Runnable() { public void run() { SwingUtilities.invokeLater( new Runnable() { public void run() { Application.getApplicationFrame() .processJSVNEvent(new JSVNStatusEvent(JSVNStatusEvent.REFRESHING)); } }); SVNTreeModel partialModel = new SVNTreeModel(workingCopy, online); DefaultMutableTreeNode foo = buildTreeNode(partialModel); // reconcile updated tree with current tree reconcileNodes(node, foo); SwingUtilities.invokeLater( new Runnable() { public void run() { Application.getApplicationFrame() .processJSVNEvent(new JSVNStatusEvent(JSVNStatusEvent.READY)); } }); } }); t.start(); }
/** * returns a string of all selected targets separated by spaces, or null if nothing is selected * * @return space-separated string of targets */ private String getSelectedTargetsAsString() { TreePath[] paths = this.getSelectionPaths(); if (paths == null) { return null; } StringBuffer targets = new StringBuffer(); for (int i = 0; i < paths.length; i++) { TreePath path = paths[i]; DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent(); SVNTreeNodeData svnNode = (SVNTreeNodeData) dmtn.getUserObject(); String target = ConfigurationManager.getInstance().getConfig().getWorkingDirectory() + svnNode.getPath(); // if target contains a space, wrap the target in quotes (eg: c:\Document and Settings\...) if (target.indexOf(SPACE) > -1) { targets.append(DOUBLE_QUOTE).append(target).append(DOUBLE_QUOTE); } else { targets.append(target); } targets.append(" "); } return targets.toString().trim(); }
/** * Performs a "live-update" to the original DefaultMutableTreeNode by reconsiling the differences * between it and a given updated DefaultMutableTreeNode. The resulting original * DefaultMutableTreeNode will look identical to the updated node. Appropriate events will fire to * keep the GUI consistant with any changes that were made to the model. * * @param original the model's existing node * @param updated the node representing the model node's new state */ private void reconcileNodes(DefaultMutableTreeNode original, DefaultMutableTreeNode updated) { SVNTreeNodeData originalData = (SVNTreeNodeData) original.getUserObject(); SVNTreeNodeData updatedData = (SVNTreeNodeData) updated.getUserObject(); if (!originalData.equals(updatedData)) { originalData.copyNodeValues(updatedData); } int originalChildCount = original.getChildCount(); int insertionPoint = 0; // loop through the original node's children for (int i = insertionPoint; i < originalChildCount; i++) { // loop through remaining updated node's children boolean found = false; DefaultMutableTreeNode originalChildNode = (DefaultMutableTreeNode) original.getChildAt(insertionPoint); SVNTreeNodeData originalChildData = (SVNTreeNodeData) originalChildNode.getUserObject(); while (updated.children().hasMoreElements()) { DefaultMutableTreeNode updatedChildNode = (DefaultMutableTreeNode) updated.children().nextElement(); SVNTreeNodeData updatedChildData = (SVNTreeNodeData) updatedChildNode.getUserObject(); if (originalChildData.getPath().equals(updatedChildData.getPath())) { // same resource, check equality insertionPoint++; found = true; // remove from updated list so we know we handled this node updated.remove(updatedChildNode); if (!originalChildData.equals(updatedChildData)) { // same resource, different values -- update originalChildData.copyNodeValues(updatedChildData); reconcileNodes(originalChildNode, updatedChildNode); ((DefaultTreeModel) this.getModel()).nodeChanged(originalChildNode); break; } else { // same values, do nothing reconcileNodes(originalChildNode, updatedChildNode); break; } } else { // different resources // does updated node's child need to be inserted before original node's child? if (updatedChildData.getPath().compareTo(originalChildData.getPath()) < 0) { original.insert(updatedChildNode, insertionPoint); ((DefaultTreeModel) this.getModel()) .nodesWereInserted(original, new int[] {insertionPoint}); insertionPoint++; // inserting the node into the original has the side-effect of removing it from the // updated // node, just keep going until we've handled all children, or until the remaining // children // come after the last original node } else { break; } } } if (!found) { original.remove(insertionPoint); ((DefaultTreeModel) this.getModel()) .nodesWereRemoved( original, new int[] {insertionPoint}, new Object[] {originalChildNode}); } } // add any remaining new child nodes while (updated.children().hasMoreElements()) { DefaultMutableTreeNode updatedChildNode = (DefaultMutableTreeNode) updated.children().nextElement(); original.add(updatedChildNode); // adding the new node to the original has the side-effect of removing it from the updated // node's children // so we just keep going until no children remain ((DefaultTreeModel) this.getModel()) .nodesWereInserted(original, new int[] {insertionPoint++}); } }
/** @param ae */ public void actionPerformed(ActionEvent ae) { String targets = getSelectedTargetsAsString(); if (targets == null) { // user hasn't selected anything -- pop-up a error message } else { if (ae.getActionCommand().equals(ACTION_ADD)) { // process add request Commandable command = new Add(); Map args = new HashMap(); args.put(Add.TARGETS, targets); executeCommand(command, args); } else if (ae.getActionCommand().equals(ACTION_CAT)) { // process cat request CommandDialog dialog = new CatDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_CHECKOUT)) { // process checkout request CommandDialog dialog = new CheckoutDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_CLEANUP)) { // check that all targets are directories TreePath[] paths = this.getSelectionPaths(); for (int i = 0; i < paths.length; i++) { TreePath path = paths[i]; DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent(); SVNTreeNodeData svnNode = (SVNTreeNodeData) dmtn.getUserObject(); if (svnNode.getNodeKind() != SVNTreeNodeData.NODE_KIND_DIRECTORY) { showMessageDialog(CLEANUP_ERROR + svnNode.getPath()); return; } } // process cleanup request Commandable command = new Cleanup(); Map args = new HashMap(); args.put(Cleanup.TARGETS, targets); executeCommand(command, args); } else if (ae.getActionCommand().equals(ACTION_COMMIT)) { // process commit request CommandDialog dialog = new CommitDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_COPY)) { // process copy request CommandDialog dialog = new CopyDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_DELETE)) { // process delete request Commandable command = new Delete(); Map args = new HashMap(); args.put(Delete.TARGETS, targets); executeCommand(command, args); } else if (ae.getActionCommand().equals(ACTION_DIFF)) { // process diff request CommandDialog dialog = new DiffDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_INFO)) { // process info request Commandable command = new Info(); Map args = new HashMap(); args.put(Info.TARGETS, targets); executeCommand(command, args); } else if (ae.getActionCommand().equals(ACTION_LOG)) { // process log request CommandDialog dialog = new LogDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_LS)) { // process log request CommandDialog dialog = new LsDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_MERGE)) { // process merge request CommandDialog dialog = new MergeDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_MOVE)) { // process move request CommandDialog dialog = new MoveDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_REFRESH_ONLINE)) { // process recursive online refresh request refreshSelectedTargets(true); } else if (ae.getActionCommand().equals(ACTION_REFRESH_OFFLINE)) { // process recursive offline refresh request refreshSelectedTargets(false); } else if (ae.getActionCommand().equals(ACTION_RESOLVE)) { // process resolve request String message = RESOLVE_WARNING; String[] targetArray = getSelectedTargetsAsArray(); for (int i = 0; i < targetArray.length; i++) { String s = targetArray[i]; message += s + Constants.NEWLINE; } int confirmation = JOptionPane.showConfirmDialog( this, message, CONFIRMATION, JOptionPane.OK_CANCEL_OPTION); if (confirmation == JOptionPane.OK_OPTION) { // process add request Commandable command = new Resolve(); Map args = new HashMap(); args.put(Resolve.TARGETS, targets); executeCommand(command, args); } } else if (ae.getActionCommand().equals(ACTION_REVERT)) { // process revert request String message = REVERT_WARNING; String[] targetArray = getSelectedTargetsAsArray(); for (int i = 0; i < targetArray.length; i++) { String s = targetArray[i]; message += s + Constants.NEWLINE; } int confirmation = JOptionPane.showConfirmDialog( this, message, CONFIRMATION, JOptionPane.OK_CANCEL_OPTION); if (confirmation == JOptionPane.OK_OPTION) { // process add request Commandable command = new Revert(); Map args = new HashMap(); args.put(Revert.TARGETS, targets); executeCommand(command, args); } } else if (ae.getActionCommand().equals(ACTION_STATUS)) { // process status request CommandDialog dialog = new StatusDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_SWITCH)) { // process switch request CommandDialog dialog = new SwitchDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } else if (ae.getActionCommand().equals(ACTION_UPDATE)) { // process update request CommandDialog dialog = new UpdateDialog(Application.getApplicationFrame(), true); initializeAndShowDialog(dialog, targets); } } }