From: <dal...@us...> - 2008-12-30 20:32:24
|
Revision: 14257 http://jedit.svn.sourceforge.net/jedit/?rev=14257&view=rev Author: daleanson Date: 2008-12-30 20:32:19 +0000 (Tue, 30 Dec 2008) Log Message: ----------- more work on 'merge' command. Works from PV, needs to work from text area context menu and svn browser. Modified Paths: -------------- plugins/SVNPlugin/trunk/SVNPlugin.props plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/MergeAction.java plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/StatusAction.java plugins/SVNPlugin/trunk/src/ise/plugin/svn/command/Merge.java plugins/SVNPlugin/trunk/src/ise/plugin/svn/data/MergeResults.java plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/BrowseLocalRemotePanel.java Added Paths: ----------- plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/MergeResultsPanel.java Modified: plugins/SVNPlugin/trunk/SVNPlugin.props =================================================================== --- plugins/SVNPlugin/trunk/SVNPlugin.props 2008-12-30 11:20:05 UTC (rev 14256) +++ plugins/SVNPlugin/trunk/SVNPlugin.props 2008-12-30 20:32:19 UTC (rev 14257) @@ -300,7 +300,7 @@ ips.Date=Date ips.Zoom=Zoom -# for Merge dialog +# for Merge ips.Merge=Merge ips.Merge_from_this_path/revision>=Merge from this path/revision: ips.To_this_path/revision>=To this path/revision: @@ -316,6 +316,13 @@ ips.Merge_destination_not_selected.=Merge destination not selected. ips.Start_revision_not_selected.=Start revision not selected. ips.End_revision_not_selected.=End revision not selected. +ips.Files_with_conflicts>=Files with conflicts: +ips.Added_files>=Added files: +ips.Deleted_files>=Deleted files: +ips.Merged_files>=Merged files: +ips.Skipped_files>=Skipped files: +ips.Updated_files>=Updated files: +ips.Merge_Dry_Run_Results>=Merge Dry Run Results: # for MkDir dialog ips.mkdir=mkdir Modified: plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/MergeAction.java =================================================================== --- plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/MergeAction.java 2008-12-30 11:20:05 UTC (rev 14256) +++ plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/MergeAction.java 2008-12-30 20:32:19 UTC (rev 14257) @@ -34,7 +34,8 @@ import ise.plugin.svn.command.Merge; import ise.plugin.svn.data.MergeData; import ise.plugin.svn.data.MergeResults; -//import ise.plugin.svn.gui.MergeResultsPanel; +import ise.plugin.svn.data.SVNData; +import ise.plugin.svn.gui.MergeResultsPanel; import ise.plugin.svn.io.ConsolePrintStream; import ise.plugin.svn.library.swingworker.*; import java.awt.event.ActionEvent; @@ -66,7 +67,7 @@ if ( getUsername() == null ) { verifyLogin( data.getFromFile() == null ? "" : data.getFromFile().getAbsolutePath() ); if ( isCanceled() ) { - return; + return ; } data.setUsername( getUsername() ); data.setPassword( getPassword() ); @@ -78,7 +79,7 @@ final OutputPanel panel = SVNPlugin.getOutputPanel( getView() ); panel.showConsole(); Logger logger = panel.getLogger(); - logger.log( Level.INFO, jEdit.getProperty("ips.Merging...", "Merging...") ); + logger.log( Level.INFO, jEdit.getProperty( "ips.Merging...", "Merging..." ) ); for ( Handler handler : logger.getHandlers() ) { handler.flush(); } @@ -120,9 +121,24 @@ if ( results == null ) { return ; } - //JPanel results_panel = new MergeResultsPanel( get(), data.getShowPaths(), getView(), getUsername(), getPassword() ); - JPanel results_panel = new JPanel(); - panel.addTab( jEdit.getProperty( "ips.Merge", "Merge" ), results_panel ); + if ( results.isDryRun() ) { + JPanel results_panel = new MergeResultsPanel( results ); + panel.addTab( jEdit.getProperty( "ips.Merge", "Merge" ), results_panel ); + } + else { + // after doing a real merge, run a status for the results + SVNData cd = new SVNData(); + cd.addPath( data.getDestinationFile().getAbsolutePath() ); + cd.setRemote( false ); + cd.setRecursive( data.getRecursive() ); + cd.setOut( data.getOut() ); + cd.setErr( data.getErr() ); + cd.setUsername( data.getUsername() ); + cd.setPassword( data.getPassword() ); + StatusAction sa = new StatusAction( MergeAction.this.getView(), cd ); + sa.setTabTitle( jEdit.getProperty( "ips.Merge", "Merge" ) ); + sa.actionPerformed( null ); + } } catch ( Exception e ) { // ignored Modified: plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/StatusAction.java =================================================================== --- plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/StatusAction.java 2008-12-30 11:20:05 UTC (rev 14256) +++ plugins/SVNPlugin/trunk/src/ise/plugin/svn/action/StatusAction.java 2008-12-30 20:32:19 UTC (rev 14257) @@ -54,6 +54,7 @@ public class StatusAction extends SVNAction { private SVNData data = null; + private String title = jEdit.getProperty( "ips.Status", "Status" ); public StatusAction( View view, List<String> paths, String username, String password ) { super( view, jEdit.getProperty( "ips.Status", "Status" ) ); @@ -73,6 +74,17 @@ this.data = data; } + /** + * After a merge, this action is called to show the user the results of + * the merge. This method lets the merge command set the tab title to + * "Merge". + */ + public void setTabTitle( String title ) { + if ( title != null && title.length() > 0 ) { + this.title = title; + } + } + public void actionPerformed( ActionEvent ae ) { if ( data.getUsername() == null ) { verifyLogin( data.getPaths().get( 0 ) ); @@ -134,7 +146,7 @@ protected void done() { try { JPanel panel = new StatusResultsPanel( get(), getView(), getUsername(), getPassword() ); - output_panel.addTab( jEdit.getProperty( "ips.Status", "Status" ), panel ); + output_panel.addTab( title, panel ); } catch ( Exception e ) { System.err.println( e.getMessage() ); Modified: plugins/SVNPlugin/trunk/src/ise/plugin/svn/command/Merge.java =================================================================== --- plugins/SVNPlugin/trunk/src/ise/plugin/svn/command/Merge.java 2008-12-30 11:20:05 UTC (rev 14256) +++ plugins/SVNPlugin/trunk/src/ise/plugin/svn/command/Merge.java 2008-12-30 20:32:19 UTC (rev 14257) @@ -34,16 +34,25 @@ import org.tmatesoft.svn.core.wc.ISVNOptions; import org.tmatesoft.svn.core.wc.SVNClientManager; import org.tmatesoft.svn.core.wc.SVNDiffClient; -import org.tmatesoft.svn.core.wc.SVNEvent; import org.tmatesoft.svn.core.wc.SVNWCUtil; -import org.tmatesoft.svn.cli.command.SVNCommandEventProcessor; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.cli.SVNCommand; +import org.tmatesoft.svn.core.SVNCancelException; +import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.SVNProperty; +import org.tmatesoft.svn.core.internal.util.SVNFormatUtil; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNEvent; +import org.tmatesoft.svn.core.wc.SVNEventAction; +import org.tmatesoft.svn.core.wc.SVNStatusType; + import ise.plugin.svn.data.MergeData; import ise.plugin.svn.data.MergeResults; + import org.gjt.sp.jedit.jEdit; @@ -72,21 +81,15 @@ // get a diff client SVNDiffClient client = clientManager.getDiffClient(); - // results holder + // set an event handler so that messages go to the merge data streams for display MergeResults results = new MergeResults(); + results.setDryRun(data.getDryRun()); + results.setCommandLineEquivalent(data.commandLineEquivalent()); + MergeEventProcessor handler = new MergeEventProcessor( data.getOut(), results ); + client.setEventHandler( handler ); - // set an event handler so that messages go to the merge data streams for display - client.setEventHandler( - new SVNCommandEventProcessor( data.getOut(), data.getErr(), false ) { - @Override - public void handleEvent( SVNEvent event, double progress ) { - super.handleEvent( event, progress ); - } - } - ); - try { - System.out.println(data.toString()); + System.out.println( data.toString() ); if ( data.getFromFile() != null && data.getToFile() != null ) { //local, revision, local, revision, destination System.out.println( "+++++ method 1" ); @@ -145,14 +148,113 @@ } else { String msg = data.checkValid(); - results.setErrorMessage( msg == null ? jEdit.getProperty( "ips.Merge_data_error.", "Merge data error." ) : msg ); + handler.getResults().setErrorMessage( msg == null ? jEdit.getProperty( "ips.Merge_data_error.", "Merge data error." ) : msg ); } } catch ( Exception e ) { e.printStackTrace(); } - return results; + return handler.getResults(); } + class MergeEventProcessor implements ISVNEventHandler { + + private final PrintStream out; + private MergeResults results = null; + + + public MergeEventProcessor( PrintStream out, MergeResults results ) { + this.out = out; + this.results = results; + } + + public MergeResults getResults() { + return results; + } + + public void handleEvent( SVNEvent event, double progress ) { + String filename = ""; + if ( event.getFile() != null ) { + filename = SVNFormatUtil.formatPath( event.getFile() ); + } + if ( event.getAction() == SVNEventAction.UPDATE_ADD ) { + if ( event.getContentsStatus() == SVNStatusType.CONFLICTED ) { + SVNCommand.println( out, "C " + filename ); + results.addConflicted( filename ); + } + else { + SVNCommand.println( out, "A " + filename ); + results.addAdded( filename ); + } + } + else if ( event.getAction() == SVNEventAction.UPDATE_DELETE ) { + SVNCommand.println( out, "D " + filename ); + results.addDeleted( filename ); + } + else if ( event.getAction() == SVNEventAction.UPDATE_UPDATE ) { + StringBuffer sb = new StringBuffer(); + if ( event.getNodeKind() != SVNNodeKind.DIR ) { + if ( event.getContentsStatus() == SVNStatusType.CHANGED ) { + sb.append( "U" ); + results.addUpdated( filename ); + } + else if ( event.getContentsStatus() == SVNStatusType.CONFLICTED ) { + sb.append( "C" ); + results.addConflicted( filename ); + } + else if ( event.getContentsStatus() == SVNStatusType.MERGED ) { + sb.append( "G" ); + results.addMerged( filename ); + } + else { + sb.append( " " ); + } + } + else { + sb.append( ' ' ); + } + if ( event.getPropertiesStatus() == SVNStatusType.CHANGED ) { + sb.append( "U" ); + results.addUpdated( filename ); + } + else if ( event.getPropertiesStatus() == SVNStatusType.CONFLICTED ) { + sb.append( "C" ); + results.addConflicted( filename ); + } + else if ( event.getPropertiesStatus() == SVNStatusType.MERGED ) { + sb.append( "G" ); + results.addMerged( filename ); + } + else { + sb.append( " " ); + } + if ( sb.toString().trim().length() > 0 ) { + SVNCommand.println( out, sb.toString() + " " + filename ); + } + } + else if ( event.getAction() == SVNEventAction.ADD ) { + if ( SVNProperty.isBinaryMimeType( event.getMimeType() ) ) { + SVNCommand.println( out, "A (bin) " + filename ); + results.addAdded( filename ); + } + else { + SVNCommand.println( out, "A " + filename ); + results.addAdded( filename ); + } + } + else if ( event.getAction() == SVNEventAction.DELETE ) { + SVNCommand.println( out, "D " + filename ); + results.addDeleted( filename ); + } + else if ( event.getAction() == SVNEventAction.SKIP ) { + SVNCommand.println( out, "Skipped '" + filename + "'" ); + results.addSkipped( filename ); + } + } + + public void checkCancelled() throws SVNCancelException {} + + + } } \ No newline at end of file Modified: plugins/SVNPlugin/trunk/src/ise/plugin/svn/data/MergeResults.java =================================================================== --- plugins/SVNPlugin/trunk/src/ise/plugin/svn/data/MergeResults.java 2008-12-30 11:20:05 UTC (rev 14256) +++ plugins/SVNPlugin/trunk/src/ise/plugin/svn/data/MergeResults.java 2008-12-30 20:32:19 UTC (rev 14257) @@ -29,12 +29,173 @@ package ise.plugin.svn.data; import java.io.Serializable; +import java.util.List; +import java.util.ArrayList; +/** + * Data transfer object for the results of a merge. + */ public class MergeResults implements Serializable { + + // if there is any error during the merge, this field will contain a + // non-null message for display private String errorMessage = null; + // lists of files that fall into particular merge categories + private List<String> conflicted = null; + private List<String> added = null; + private List<String> deleted = null; + private List<String> merged = null; + private List<String> skipped = null; + private List<String> updated = null; + private boolean dryRun = true; + + private String commandLineEquivalent; /** + * Returns the value of commandLineEquivalent. + */ + public String getCommandLineEquivalent() { + return commandLineEquivalent; + } + + /** + * Sets the value of commandLineEquivalent. + * @param commandLineEquivalent The value to assign commandLineEquivalent. + */ + public void setCommandLineEquivalent(String commandLineEquivalent) { + this.commandLineEquivalent = commandLineEquivalent; + } + + /** + * Returns the value of dryRun. + */ + public boolean isDryRun() { + return dryRun; + } + + /** + * Sets the value of dryRun. + * @param dryRun The value to assign dryRun. + */ + public void setDryRun( boolean dryRun ) { + this.dryRun = dryRun; + } + + /** + * Sets the value of conflicted. + * @param conflicted The value to assign conflicted. + */ + public void addConflicted( String filename ) { + if ( conflicted == null ) { + conflicted = new ArrayList<String>(); + } + conflicted.add( filename ); + } + + /** + * Sets the value of added. + * @param added The value to assign added. + */ + public void addAdded( String filename ) { + if ( added == null ) { + added = new ArrayList<String>(); + } + added.add( filename ); + } + + /** + * Sets the value of deleted. + * @param deleted The value to assign deleted. + */ + public void addDeleted( String filename ) { + if ( deleted == null ) { + deleted = new ArrayList<String>(); + } + deleted.add( filename ); + } + + /** + * Sets the value of merged. + * @param merged The value to assign merged. + */ + public void addMerged( String filename ) { + if ( merged == null ) { + merged = new ArrayList<String>(); + } + merged.add( filename ); + } + + /** + * Sets the value of skipped. + * @param skipped The value to assign skipped. + */ + public void addSkipped( String filename ) { + if ( skipped == null ) { + skipped = new ArrayList<String>(); + } + skipped.add( filename ); + } + + /** + * Sets the value of updated. + * @param updated The value to assign updated. + */ + public void addUpdated( String filename ) { + if ( updated == null ) { + updated = new ArrayList<String>(); + } + updated.add( filename ); + } + + + /** + * Returns the value of conflicted. + */ + public List<String> getConflicted() { + return conflicted; + } + + + /** + * Returns the value of added. + */ + public List<String> getAdded() { + return added; + } + + + /** + * Returns the value of deleted. + */ + public List<String> getDeleted() { + return deleted; + } + + + /** + * Returns the value of merged. + */ + public List<String> getMerged() { + return merged; + } + + + /** + * Returns the value of skipped. + */ + public List<String> getSkipped() { + return skipped; + } + + /** + * Returns the value of updated. + */ + public List<String> getUpdated() { + return updated; + } + + /** * Returns the value of errorMessage. */ public String getErrorMessage() { @@ -49,6 +210,4 @@ this.errorMessage = errorMessage; } - - } \ No newline at end of file Modified: plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/BrowseLocalRemotePanel.java =================================================================== --- plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/BrowseLocalRemotePanel.java 2008-12-30 11:20:05 UTC (rev 14256) +++ plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/BrowseLocalRemotePanel.java 2008-12-30 20:32:19 UTC (rev 14257) @@ -30,6 +30,7 @@ // imports import java.io.File; +import java.net.URL; import java.util.*; import java.awt.event.*; import javax.swing.*; @@ -61,7 +62,6 @@ private String startPath = null; private String endPath = null; private HistoryTextField path = null; - private boolean destinationIsLocal = true; public BrowseLocalRemotePanel( View view, String labelText, String start_path, String end_path ) { this( view, labelText, start_path, end_path, true ); @@ -92,7 +92,6 @@ String filename = dirs[ 0 ]; File f = new File( filename ); path.setText( f.getAbsolutePath() ); - destinationIsLocal = true; path.addCurrentToHistory(); } } @@ -121,7 +120,6 @@ dialog.dispose(); if ( selection != null && selection.length() > 0 ) { path.setText( selection ); - destinationIsLocal = false; path.addCurrentToHistory(); } } @@ -185,7 +183,13 @@ } public boolean isDestinationLocal() { - return destinationIsLocal; + try { + new URL(getPath()); + return false; + } + catch(Exception e) { + return true; + } } public void addDocumentListener( DocumentListener listener ) { Added: plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/MergeResultsPanel.java =================================================================== --- plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/MergeResultsPanel.java (rev 0) +++ plugins/SVNPlugin/trunk/src/ise/plugin/svn/gui/MergeResultsPanel.java 2008-12-30 20:32:19 UTC (rev 14257) @@ -0,0 +1,149 @@ +/* +Copyright (c) 2007, Dale Anson +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +* Neither the name of the author nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ise.plugin.svn.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.event.*; +import java.util.*; +import javax.swing.*; +import javax.swing.table.*; +import javax.swing.tree.*; +import javax.swing.border.EmptyBorder; +import ise.plugin.svn.data.MergeResults; +import ise.plugin.svn.action.*; +import org.gjt.sp.jedit.jEdit; + +/** + * Shows the results of a dry-run merge. Non-dry-run merge results are shown + * in a StatusResultsPanel. There are no actions associated with this display. + */ +public class MergeResultsPanel extends JPanel { + + private JTree tree = null; + + private static Color background = jEdit.getColorProperty("view.bgColor", Color.WHITE); + private static Color selection = jEdit.getColorProperty("view.selectionColor", Color.LIGHT_GRAY); + + + public MergeResultsPanel( MergeResults results ) { + super( new BorderLayout() ); + + setBorder( new EmptyBorder( 3, 3, 3, 3 ) ); + + JTextArea label = new JTextArea(); + label.setText(jEdit.getProperty("ips.Merge_Dry_Run_Results>", "Merge Dry Run Results:") + "\n" + results.getCommandLineEquivalent() ); + label.setEditable(false); + label.setBorder( new EmptyBorder( 6, 3, 6, 3 ) ); + + boolean added = false; + + DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + + List<String> list = results.getConflicted(); + if ( list != null ) { + root.add( createNode( jEdit.getProperty("ips.Files_with_conflicts>", "Files with conflicts:"), list ) ); + added = true; + } + + list = results.getAdded(); + if ( list != null ) { + root.add( createNode( jEdit.getProperty("ips.Added_files>", "Added files:"), list ) ); + added = true; + } + + list = results.getDeleted(); + if ( list != null ) { + root.add( createNode( jEdit.getProperty("ips.Deleted_files>", "Deleted files:"), list ) ); + added = true; + } + + list = results.getMerged(); + if ( list != null ) { + root.add( createNode( jEdit.getProperty("ips.Merged_files>", "Merged files:"), list ) ); + added = true; + } + + list = results.getSkipped(); + if ( list != null ) { + root.add( createNode( jEdit.getProperty("ips.Skipped_files>", "Skipped files:"), list ) ); + added = true; + } + + list = results.getUpdated(); + if ( list != null ) { + root.add( createNode( jEdit.getProperty("ips.Updated_files>", "Updated files:"), list ) ); + added = true; + } + + if ( added ) { + tree = new JTree( root ); + tree.setRootVisible( false ); + tree.setCellRenderer(new CellRenderer()); + for ( int i = 0; i < tree.getRowCount(); i++ ) { + tree.expandRow( i ); + } + add( tree, BorderLayout.CENTER ); + } + else { + label.setText( label.getText() + "\n\n" + jEdit.getProperty("ips.(All_files_up_to_date.)", "(All files up to date.)") ); + } + add( label, BorderLayout.NORTH ); + } + + private DefaultMutableTreeNode createNode( String title, List<String> values ) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode( title ); + for ( String filename : values ) { + DefaultMutableTreeNode child = new DefaultMutableTreeNode( filename ); + node.add( child ); + } + return node; + } + + class CellRenderer extends DefaultTreeCellRenderer { + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus ) { + + Component r = super.getTreeCellRendererComponent( + tree, value, sel, + expanded, leaf, row, + hasFocus ); + + r.setBackground( sel ? MergeResultsPanel.selection : MergeResultsPanel.background ); + return r; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |