|
Lines 10-15
Link Here
|
| 10 |
*******************************************************************************/ |
10 |
*******************************************************************************/ |
| 11 |
package org.eclipse.ui.actions; |
11 |
package org.eclipse.ui.actions; |
| 12 |
|
12 |
|
|
|
13 |
import java.net.URI; |
| 14 |
|
| 13 |
import org.eclipse.core.resources.IContainer; |
15 |
import org.eclipse.core.resources.IContainer; |
| 14 |
import org.eclipse.core.resources.IFile; |
16 |
import org.eclipse.core.resources.IFile; |
| 15 |
import org.eclipse.core.resources.IResource; |
17 |
import org.eclipse.core.resources.IResource; |
|
Lines 19-24
Link Here
|
| 19 |
import org.eclipse.core.runtime.IPath; |
21 |
import org.eclipse.core.runtime.IPath; |
| 20 |
import org.eclipse.core.runtime.IProgressMonitor; |
22 |
import org.eclipse.core.runtime.IProgressMonitor; |
| 21 |
import org.eclipse.core.runtime.OperationCanceledException; |
23 |
import org.eclipse.core.runtime.OperationCanceledException; |
|
|
24 |
import org.eclipse.core.runtime.Path; |
| 22 |
import org.eclipse.core.runtime.SubProgressMonitor; |
25 |
import org.eclipse.core.runtime.SubProgressMonitor; |
| 23 |
import org.eclipse.osgi.util.NLS; |
26 |
import org.eclipse.osgi.util.NLS; |
| 24 |
import org.eclipse.swt.widgets.Shell; |
27 |
import org.eclipse.swt.widgets.Shell; |
|
Lines 34-226
Link Here
|
| 34 |
*/ |
37 |
*/ |
| 35 |
public class MoveFilesAndFoldersOperation extends CopyFilesAndFoldersOperation { |
38 |
public class MoveFilesAndFoldersOperation extends CopyFilesAndFoldersOperation { |
| 36 |
|
39 |
|
| 37 |
/** |
40 |
/** |
| 38 |
* Creates a new operation initialized with a shell. |
41 |
* Creates a new operation initialized with a shell. |
| 39 |
* |
42 |
* |
| 40 |
* @param shell parent shell for error dialogs |
43 |
* @param shell |
| 41 |
*/ |
44 |
* parent shell for error dialogs |
| 42 |
public MoveFilesAndFoldersOperation(Shell shell) { |
45 |
*/ |
| 43 |
super(shell); |
46 |
public MoveFilesAndFoldersOperation(Shell shell) { |
| 44 |
} |
47 |
super(shell); |
| 45 |
|
48 |
} |
| 46 |
/** |
49 |
|
| 47 |
* Returns whether this operation is able to perform on-the-fly |
50 |
/** |
| 48 |
* auto-renaming of resources with name collisions. |
51 |
* Returns whether this operation is able to perform on-the-fly |
| 49 |
* |
52 |
* auto-renaming of resources with name collisions. |
| 50 |
* @return <code>true</code> if auto-rename is supported, |
53 |
* |
| 51 |
* and <code>false</code> otherwise |
54 |
* @return <code>true</code> if auto-rename is supported, and |
| 52 |
*/ |
55 |
* <code>false</code> otherwise |
| 53 |
protected boolean canPerformAutoRename() { |
56 |
*/ |
| 54 |
return false; |
57 |
protected boolean canPerformAutoRename() { |
| 55 |
} |
58 |
return false; |
| 56 |
|
59 |
} |
| 57 |
/** |
60 |
|
| 58 |
* Moves the resources to the given destination. This method is |
61 |
/** |
| 59 |
* called recursively to merge folders during folder move. |
62 |
* Moves the resources to the given destination. This method is called |
| 60 |
* |
63 |
* recursively to merge folders during folder move. |
| 61 |
* @param resources the resources to move |
64 |
* |
| 62 |
* @param destination destination to which resources will be moved |
65 |
* @param resources |
| 63 |
* @param subMonitor a progress monitor for showing progress and for cancelation |
66 |
* the resources to move |
| 64 |
*/ |
67 |
* @param destination |
| 65 |
protected void copy(IResource[] resources, IPath destination, |
68 |
* destination to which resources will be moved |
| 66 |
IProgressMonitor subMonitor) throws CoreException { |
69 |
* @param subMonitor |
| 67 |
for (int i = 0; i < resources.length; i++) { |
70 |
* a progress monitor for showing progress and for cancelation |
| 68 |
IResource source = resources[i]; |
71 |
*/ |
| 69 |
IPath destinationPath = destination.append(source.getName()); |
72 |
protected void copy(IResource[] resources, IPath destination, |
| 70 |
IWorkspace workspace = source.getWorkspace(); |
73 |
IProgressMonitor subMonitor) throws CoreException { |
| 71 |
IWorkspaceRoot workspaceRoot = workspace.getRoot(); |
74 |
for (int i = 0; i < resources.length; i++) { |
| 72 |
IResource existing = workspaceRoot.findMember(destinationPath); |
75 |
IResource source = resources[i]; |
| 73 |
if (source.getType() == IResource.FOLDER && existing != null) { |
76 |
IPath destinationPath = destination.append(source.getName()); |
| 74 |
// the resource is a folder and it exists in the destination, move the |
77 |
IWorkspace workspace = source.getWorkspace(); |
| 75 |
// children of the folder. |
78 |
IWorkspaceRoot workspaceRoot = workspace.getRoot(); |
| 76 |
if (homogenousResources(source, existing)) { |
79 |
IResource existing = workspaceRoot.findMember(destinationPath); |
| 77 |
IResource[] children = ((IContainer) source).members(); |
80 |
if (source.getType() == IResource.FOLDER && existing != null) { |
| 78 |
copy(children, destinationPath, subMonitor); |
81 |
// the resource is a folder and it exists in the destination, |
| 79 |
delete(source, subMonitor); |
82 |
// move the |
| 80 |
} else { |
83 |
// children of the folder. |
| 81 |
// delete the destination folder, moving a linked folder |
84 |
if (homogenousResources(source, existing)) { |
| 82 |
// over an unlinked one or vice versa. Fixes bug 28772. |
85 |
IResource[] children = ((IContainer) source).members(); |
| 83 |
delete(existing, new SubProgressMonitor(subMonitor, 0)); |
86 |
copy(children, destinationPath, subMonitor); |
| 84 |
source.move(destinationPath, IResource.SHALLOW |
87 |
delete(source, subMonitor); |
| 85 |
| IResource.KEEP_HISTORY, new SubProgressMonitor( |
88 |
} else { |
| 86 |
subMonitor, 0)); |
89 |
// delete the destination folder, moving a linked folder |
| 87 |
} |
90 |
// over an unlinked one or vice versa. Fixes bug 28772. |
| 88 |
} else { |
91 |
delete(existing, new SubProgressMonitor(subMonitor, 0)); |
| 89 |
// if we're merging folders, we could be overwriting an existing file |
92 |
source.move(destinationPath, IResource.SHALLOW |
| 90 |
if (existing != null) { |
93 |
| IResource.KEEP_HISTORY, new SubProgressMonitor( |
| 91 |
if (homogenousResources(source, existing)) { |
94 |
subMonitor, 0)); |
|
|
95 |
} |
| 96 |
} else { |
| 97 |
// if we're merging folders, we could be overwriting an existing |
| 98 |
// file |
| 99 |
if (existing != null) { |
| 100 |
if (homogenousResources(source, existing)) { |
| 92 |
moveExisting(source, existing, subMonitor); |
101 |
moveExisting(source, existing, subMonitor); |
| 93 |
} else { |
102 |
} else { |
| 94 |
// Moving a linked resource over unlinked or vice versa. |
103 |
// Moving a linked resource over unlinked or vice versa. |
| 95 |
// Can't use setContents here. Fixes bug 28772. |
104 |
// Can't use setContents here. Fixes bug 28772. |
| 96 |
delete(existing, new SubProgressMonitor(subMonitor, 0)); |
105 |
delete(existing, new SubProgressMonitor(subMonitor, 0)); |
| 97 |
source.move(destinationPath, IResource.SHALLOW |
106 |
source.move(destinationPath, IResource.SHALLOW |
| 98 |
| IResource.KEEP_HISTORY, |
107 |
| IResource.KEEP_HISTORY, |
| 99 |
new SubProgressMonitor(subMonitor, 0)); |
108 |
new SubProgressMonitor(subMonitor, 0)); |
| 100 |
} |
109 |
} |
| 101 |
} else { |
110 |
} else { |
| 102 |
source.move(destinationPath, IResource.SHALLOW |
111 |
source.move(destinationPath, IResource.SHALLOW |
| 103 |
| IResource.KEEP_HISTORY, new SubProgressMonitor( |
112 |
| IResource.KEEP_HISTORY, new SubProgressMonitor( |
| 104 |
subMonitor, 0)); |
113 |
subMonitor, 0)); |
| 105 |
} |
114 |
} |
| 106 |
subMonitor.worked(1); |
115 |
subMonitor.worked(1); |
| 107 |
if (subMonitor.isCanceled()) { |
116 |
if (subMonitor.isCanceled()) { |
| 108 |
throw new OperationCanceledException(); |
117 |
throw new OperationCanceledException(); |
| 109 |
} |
118 |
} |
| 110 |
} |
119 |
} |
| 111 |
} |
120 |
} |
| 112 |
} |
121 |
} |
| 113 |
|
122 |
|
| 114 |
/** |
123 |
/** |
| 115 |
* Returns the message for querying deep copy/move of a linked |
124 |
* Returns the message for querying deep copy/move of a linked resource. |
| 116 |
* resource. |
125 |
* |
| 117 |
* |
126 |
* @param source |
| 118 |
* @param source resource the query is made for |
127 |
* resource the query is made for |
| 119 |
* @return the deep query message |
128 |
* @return the deep query message |
| 120 |
*/ |
129 |
*/ |
| 121 |
protected String getDeepCheckQuestion(IResource source) { |
130 |
protected String getDeepCheckQuestion(IResource source) { |
| 122 |
return NLS.bind(IDEWorkbenchMessages.CopyFilesAndFoldersOperation_deepMoveQuestion, source.getFullPath().makeRelative()); |
131 |
return NLS |
| 123 |
} |
132 |
.bind( |
| 124 |
|
133 |
IDEWorkbenchMessages.CopyFilesAndFoldersOperation_deepMoveQuestion, |
| 125 |
/** |
134 |
source.getFullPath().makeRelative()); |
| 126 |
* Returns the task title for this operation's progress dialog. |
135 |
} |
| 127 |
* |
136 |
|
| 128 |
* @return the task title |
137 |
/** |
| 129 |
*/ |
138 |
* Returns the task title for this operation's progress dialog. |
| 130 |
protected String getOperationTitle() { |
139 |
* |
| 131 |
return IDEWorkbenchMessages.MoveFilesAndFoldersOperation_operationTitle; |
140 |
* @return the task title |
| 132 |
} |
141 |
*/ |
| 133 |
|
142 |
protected String getOperationTitle() { |
| 134 |
/** |
143 |
return IDEWorkbenchMessages.MoveFilesAndFoldersOperation_operationTitle; |
| 135 |
* Returns the message for this operation's problems dialog. |
144 |
} |
| 136 |
* |
145 |
|
| 137 |
* @return the problems message |
146 |
/** |
| 138 |
*/ |
147 |
* Returns the message for this operation's problems dialog. |
| 139 |
protected String getProblemsMessage() { |
148 |
* |
| 140 |
return IDEWorkbenchMessages.MoveFilesAndFoldersOperation_problemMessage; |
149 |
* @return the problems message |
| 141 |
} |
150 |
*/ |
| 142 |
|
151 |
protected String getProblemsMessage() { |
| 143 |
/** |
152 |
return IDEWorkbenchMessages.MoveFilesAndFoldersOperation_problemMessage; |
| 144 |
* Returns the title for this operation's problems dialog. |
153 |
} |
| 145 |
* |
154 |
|
| 146 |
* @return the problems dialog title |
155 |
/** |
| 147 |
*/ |
156 |
* Returns the title for this operation's problems dialog. |
| 148 |
protected String getProblemsTitle() { |
157 |
* |
| 149 |
return IDEWorkbenchMessages.MoveFilesAndFoldersOperation_moveFailedTitle; |
158 |
* @return the problems dialog title |
| 150 |
} |
159 |
*/ |
| 151 |
|
160 |
protected String getProblemsTitle() { |
| 152 |
/** |
161 |
return IDEWorkbenchMessages.MoveFilesAndFoldersOperation_moveFailedTitle; |
| 153 |
* Returns whether the source file in a destination collision |
162 |
} |
| 154 |
* will be validateEdited together with the collision itself. |
163 |
|
| 155 |
* Returns true. |
164 |
/** |
| 156 |
* |
165 |
* Returns whether the source file in a destination collision will be |
| 157 |
* @return boolean <code>true</code>, the source file in a |
166 |
* validateEdited together with the collision itself. Returns true. |
| 158 |
* destination collision should be validateEdited. |
167 |
* |
| 159 |
*/ |
168 |
* @return boolean <code>true</code>, the source file in a destination |
| 160 |
protected boolean getValidateConflictSource() { |
169 |
* collision should be validateEdited. |
| 161 |
return true; |
170 |
*/ |
| 162 |
} |
171 |
protected boolean getValidateConflictSource() { |
| 163 |
|
172 |
return true; |
| 164 |
/** |
173 |
} |
| 165 |
* Sets the content of the existing file to the source file content. |
174 |
|
| 166 |
* Deletes the source file. |
175 |
/** |
| 167 |
* |
176 |
* Sets the content of the existing file to the source file content. Deletes |
| 168 |
* @param source source file to move |
177 |
* the source file. |
| 169 |
* @param existing existing file to set the source content in |
178 |
* |
| 170 |
* @param subMonitor a progress monitor for showing progress and for cancelation |
179 |
* @param source |
| 171 |
* @throws CoreException setContents failed |
180 |
* source file to move |
| 172 |
*/ |
181 |
* @param existing |
| 173 |
private void moveExisting(IResource source, IResource existing, |
182 |
* existing file to set the source content in |
| 174 |
IProgressMonitor subMonitor) throws CoreException { |
183 |
* @param subMonitor |
| 175 |
IFile existingFile = getFile(existing); |
184 |
* a progress monitor for showing progress and for cancelation |
| 176 |
|
185 |
* @throws CoreException |
| 177 |
if (existingFile != null) { |
186 |
* setContents failed |
| 178 |
IFile sourceFile = getFile(source); |
187 |
*/ |
| 179 |
|
188 |
private void moveExisting(IResource source, IResource existing, |
| 180 |
if (sourceFile != null) { |
189 |
IProgressMonitor subMonitor) throws CoreException { |
| 181 |
existingFile.setContents(sourceFile.getContents(), |
190 |
IFile existingFile = getFile(existing); |
| 182 |
IResource.KEEP_HISTORY, new SubProgressMonitor( |
191 |
|
| 183 |
subMonitor, 0)); |
192 |
if (existingFile != null) { |
| 184 |
delete(sourceFile, subMonitor); |
193 |
IFile sourceFile = getFile(source); |
| 185 |
} |
194 |
|
| 186 |
} |
195 |
if (sourceFile != null) { |
| 187 |
} |
196 |
existingFile.setContents(sourceFile.getContents(), |
| 188 |
|
197 |
IResource.KEEP_HISTORY, new SubProgressMonitor( |
| 189 |
/* (non-Javadoc) |
198 |
subMonitor, 0)); |
| 190 |
* Overrides method in CopyFilesAndFoldersOperation |
199 |
delete(sourceFile, subMonitor); |
| 191 |
* |
200 |
} |
| 192 |
* Note this method is for internal use only. It is not API. |
201 |
} |
| 193 |
* |
202 |
} |
| 194 |
*/ |
203 |
|
| 195 |
public String validateDestination(IContainer destination, |
204 |
|
| 196 |
IResource[] sourceResources) { |
205 |
/* (non-Javadoc) |
| 197 |
IPath destinationLocation = destination.getLocation(); |
206 |
* @see org.eclipse.ui.actions.CopyFilesAndFoldersOperation#validateDestination(org.eclipse.core.resources.IContainer, org.eclipse.core.resources.IResource[]) |
| 198 |
|
207 |
* Note this method is for internal use only. It is not API. |
| 199 |
for (int i = 0; i < sourceResources.length; i++) { |
208 |
*/ |
| 200 |
IResource sourceResource = sourceResources[i]; |
209 |
public String validateDestination(IContainer destination, |
| 201 |
|
210 |
IResource[] sourceResources) { |
| 202 |
// is the source being copied onto itself? |
211 |
URI destinationLocation = destination.getLocationURI(); |
| 203 |
if (sourceResource.getParent().equals(destination)) { |
212 |
IPath destinationPath = null; |
| 204 |
return NLS.bind(IDEWorkbenchMessages.MoveFilesAndFoldersOperation_sameSourceAndDest, sourceResource.getName()); |
213 |
|
| 205 |
} |
214 |
if (destinationLocation != null) |
| 206 |
// test if linked source is copied onto itself. Fixes bug 29913. |
215 |
destinationPath = new Path(destinationLocation.toString()); |
| 207 |
if (destinationLocation != null) { |
216 |
|
| 208 |
IPath sourceLocation = sourceResource.getLocation(); |
217 |
for (int i = 0; i < sourceResources.length; i++) { |
| 209 |
IPath destinationResource = destinationLocation |
218 |
IResource sourceResource = sourceResources[i]; |
| 210 |
.append(sourceResource.getName()); |
219 |
|
| 211 |
if (sourceLocation != null |
220 |
// is the source being copied onto itself? |
| 212 |
&& sourceLocation.isPrefixOf(destinationResource)) { |
221 |
if (sourceResource.getParent().equals(destination)) { |
| 213 |
return NLS.bind(IDEWorkbenchMessages.MoveFilesAndFoldersOperation_sameSourceAndDest, sourceResource.getName()); |
222 |
return NLS |
| 214 |
} |
223 |
.bind( |
| 215 |
} |
224 |
IDEWorkbenchMessages.MoveFilesAndFoldersOperation_sameSourceAndDest, |
| 216 |
} |
225 |
sourceResource.getName()); |
| 217 |
return super.validateDestination(destination, sourceResources); |
226 |
} |
| 218 |
} |
227 |
// test if linked source is copied onto itself. Fixes bug 29913. |
| 219 |
|
228 |
if (destinationPath != null) { |
| 220 |
/* (non-Javadoc) |
229 |
URI sourceLocation = sourceResource.getLocationURI(); |
| 221 |
* @see org.eclipse.ui.actions.CopyFilesAndFoldersOperation#isMove() |
230 |
if (sourceLocation != null) { |
| 222 |
*/ |
231 |
IPath sourcePath = new Path(sourceLocation.toString()); |
| 223 |
protected boolean isMove() { |
232 |
|
| 224 |
return true; |
233 |
IPath destinationResource = destinationPath |
| 225 |
} |
234 |
.append(sourceResource.getName()); |
|
|
235 |
|
| 236 |
if (sourcePath.isPrefixOf(destinationResource)) |
| 237 |
return NLS |
| 238 |
.bind( |
| 239 |
IDEWorkbenchMessages.MoveFilesAndFoldersOperation_sameSourceAndDest, |
| 240 |
sourceResource.getName()); |
| 241 |
} |
| 242 |
} |
| 243 |
} |
| 244 |
return super.validateDestination(destination, sourceResources); |
| 245 |
} |
| 246 |
|
| 247 |
/* |
| 248 |
* (non-Javadoc) |
| 249 |
* |
| 250 |
* @see org.eclipse.ui.actions.CopyFilesAndFoldersOperation#isMove() |
| 251 |
*/ |
| 252 |
protected boolean isMove() { |
| 253 |
return true; |
| 254 |
} |
| 226 |
} |
255 |
} |