1 11 package org.eclipse.ui.actions; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.core.commands.ExecutionException; 17 import org.eclipse.core.resources.IResource; 18 import org.eclipse.core.resources.IWorkspace; 19 import org.eclipse.core.resources.IWorkspaceRoot; 20 import org.eclipse.core.resources.ResourceAttributes; 21 import org.eclipse.core.runtime.CoreException; 22 import org.eclipse.core.runtime.IPath; 23 import org.eclipse.core.runtime.IProgressMonitor; 24 import org.eclipse.core.runtime.IStatus; 25 import org.eclipse.core.runtime.Status; 26 import org.eclipse.jface.dialogs.IInputValidator; 27 import org.eclipse.jface.dialogs.InputDialog; 28 import org.eclipse.jface.dialogs.MessageDialog; 29 import org.eclipse.jface.operation.IRunnableWithProgress; 30 import org.eclipse.jface.viewers.IStructuredSelection; 31 import org.eclipse.jface.window.Window; 32 import org.eclipse.swt.SWT; 33 import org.eclipse.swt.custom.TreeEditor; 34 import org.eclipse.swt.events.FocusAdapter; 35 import org.eclipse.swt.events.FocusEvent; 36 import org.eclipse.swt.graphics.Point; 37 import org.eclipse.swt.widgets.Composite; 38 import org.eclipse.swt.widgets.Control; 39 import org.eclipse.swt.widgets.Event; 40 import org.eclipse.swt.widgets.Listener; 41 import org.eclipse.swt.widgets.Shell; 42 import org.eclipse.swt.widgets.Text; 43 import org.eclipse.swt.widgets.Tree; 44 import org.eclipse.swt.widgets.TreeItem; 45 import org.eclipse.ui.PlatformUI; 46 import org.eclipse.ui.ide.undo.MoveResourcesOperation; 47 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; 48 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; 49 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; 50 import org.eclipse.ui.internal.ide.IIDEHelpContextIds; 51 52 import com.ibm.icu.text.MessageFormat; 53 54 60 public class RenameResourceAction extends WorkspaceAction { 61 62 67 private TreeEditor treeEditor; 68 69 private Tree navigatorTree; 70 71 private Text textEditor; 72 73 private Composite textEditorParent; 74 75 private TextActionHandler textActionHandler; 76 77 private IResource inlinedResource; 79 80 private boolean saving = false; 81 82 85 public static final String ID = PlatformUI.PLUGIN_ID 86 + ".RenameResourceAction"; 88 91 private IPath newPath; 92 93 private String [] modelProviderIds; 94 95 private static final String CHECK_RENAME_TITLE = IDEWorkbenchMessages.RenameResourceAction_checkTitle; 96 97 private static final String CHECK_RENAME_MESSAGE = IDEWorkbenchMessages.RenameResourceAction_readOnlyCheck; 98 99 private static String RESOURCE_EXISTS_TITLE = IDEWorkbenchMessages.RenameResourceAction_resourceExists; 100 101 private static String RESOURCE_EXISTS_MESSAGE = IDEWorkbenchMessages.RenameResourceAction_overwriteQuestion; 102 103 private static String PROJECT_EXISTS_MESSAGE = IDEWorkbenchMessages.RenameResourceAction_overwriteProjectQuestion; 104 105 private static String PROJECT_EXISTS_TITLE = IDEWorkbenchMessages.RenameResourceAction_projectExists; 106 107 114 public RenameResourceAction(Shell shell) { 115 super(shell, IDEWorkbenchMessages.RenameResourceAction_text); 116 setToolTipText(IDEWorkbenchMessages.RenameResourceAction_toolTip); 117 setId(ID); 118 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, 119 IIDEHelpContextIds.RENAME_RESOURCE_ACTION); 120 } 121 122 130 public RenameResourceAction(Shell shell, Tree tree) { 131 this(shell); 132 this.navigatorTree = tree; 133 this.treeEditor = new TreeEditor(tree); 134 } 135 136 145 private boolean checkOverwrite(final Shell shell, 146 final IResource destination) { 147 148 final boolean[] result = new boolean[1]; 149 150 153 Runnable query = new Runnable () { 154 public void run() { 155 String pathName = destination.getFullPath().makeRelative() 156 .toString(); 157 String message = RESOURCE_EXISTS_MESSAGE; 158 String title = RESOURCE_EXISTS_TITLE; 159 if (destination.getType() == IResource.PROJECT) { 160 message = PROJECT_EXISTS_MESSAGE; 161 title = PROJECT_EXISTS_TITLE; 162 } 163 result[0] = MessageDialog.openQuestion(shell, 164 title, MessageFormat.format(message, 165 new Object [] { pathName })); 166 } 167 168 }; 169 170 shell.getDisplay().syncExec(query); 171 return result[0]; 172 } 173 174 181 private boolean checkReadOnlyAndNull(IResource currentResource) { 182 if (currentResource == null) { 184 return false; 185 } 186 187 final ResourceAttributes attributes = currentResource 189 .getResourceAttributes(); 190 if (attributes != null && attributes.isReadOnly()) { 191 return MessageDialog.openQuestion(getShell(), CHECK_RENAME_TITLE, 192 MessageFormat.format(CHECK_RENAME_MESSAGE, 193 new Object [] { currentResource.getName() })); 194 } 195 196 return true; 197 } 198 199 Composite createParent() { 200 Tree tree = getTree(); 201 Composite result = new Composite(tree, SWT.NONE); 202 TreeItem[] selectedItems = tree.getSelection(); 203 treeEditor.horizontalAlignment = SWT.LEFT; 204 treeEditor.grabHorizontal = true; 205 treeEditor.setEditor(result, selectedItems[0]); 206 return result; 207 } 208 209 214 private static int getCellEditorInset(Control c) { 215 return 1; } 217 218 224 private void createTextEditor(final IResource resource) { 225 textEditorParent = createParent(); 227 textEditorParent.setVisible(false); 228 final int inset = getCellEditorInset(textEditorParent); 229 if (inset > 0) { 230 textEditorParent.addListener(SWT.Paint, new Listener() { 231 public void handleEvent(Event e) { 232 Point textSize = textEditor.getSize(); 233 Point parentSize = textEditorParent.getSize(); 234 e.gc.drawRectangle(0, 0, Math.min(textSize.x + 4, 235 parentSize.x - 1), parentSize.y - 1); 236 } 237 }); 238 } 239 textEditor = new Text(textEditorParent, SWT.NONE); 241 textEditor.setFont(navigatorTree.getFont()); 242 textEditorParent.setBackground(textEditor.getBackground()); 243 textEditor.addListener(SWT.Modify, new Listener() { 244 public void handleEvent(Event e) { 245 Point textSize = textEditor.computeSize(SWT.DEFAULT, 246 SWT.DEFAULT); 247 textSize.x += textSize.y; Point parentSize = textEditorParent.getSize(); 250 textEditor.setBounds(2, inset, Math.min(textSize.x, 251 parentSize.x - 4), parentSize.y - 2 * inset); 252 textEditorParent.redraw(); 253 } 254 }); 255 textEditor.addListener(SWT.Traverse, new Listener() { 256 public void handleEvent(Event event) { 257 258 switch (event.detail) { 261 case SWT.TRAVERSE_ESCAPE: 262 disposeTextWidget(); 264 event.doit = true; 265 event.detail = SWT.TRAVERSE_NONE; 266 break; 267 case SWT.TRAVERSE_RETURN: 268 saveChangesAndDispose(resource); 269 event.doit = true; 270 event.detail = SWT.TRAVERSE_NONE; 271 break; 272 } 273 } 274 }); 275 textEditor.addFocusListener(new FocusAdapter() { 276 public void focusLost(FocusEvent fe) { 277 saveChangesAndDispose(resource); 278 } 279 }); 280 281 if (textActionHandler != null) { 282 textActionHandler.addText(textEditor); 283 } 284 } 285 286 289 private void disposeTextWidget() { 290 if (textActionHandler != null) { 291 textActionHandler.removeText(textEditor); 292 } 293 294 if (textEditorParent != null) { 295 textEditorParent.dispose(); 296 textEditorParent = null; 297 textEditor = null; 298 treeEditor.setEditor(null, null); 299 } 300 } 301 302 309 protected List getActionResources() { 310 if (inlinedResource == null) { 311 return super.getActionResources(); 312 } 313 314 List actionResources = new ArrayList (); 315 actionResources.add(inlinedResource); 316 return actionResources; 317 } 318 319 322 protected String getOperationMessage() { 323 return IDEWorkbenchMessages.RenameResourceAction_progress; 324 } 325 326 329 protected String getProblemsMessage() { 330 return IDEWorkbenchMessages.RenameResourceAction_problemMessage; 331 } 332 333 336 protected String getProblemsTitle() { 337 return IDEWorkbenchMessages.RenameResourceAction_problemTitle; 338 } 339 340 345 private Tree getTree() { 346 return this.navigatorTree; 347 } 348 349 355 protected void invokeOperation(IResource resource, IProgressMonitor monitor) { 356 } 357 358 365 protected String queryNewResourceName(final IResource resource) { 366 final IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace(); 367 final IPath prefix = resource.getFullPath().removeLastSegments(1); 368 IInputValidator validator = new IInputValidator() { 369 public String isValid(String string) { 370 if (resource.getName().equals(string)) { 371 return IDEWorkbenchMessages.RenameResourceAction_nameMustBeDifferent; 372 } 373 IStatus status = workspace.validateName(string, resource 374 .getType()); 375 if (!status.isOK()) { 376 return status.getMessage(); 377 } 378 if (workspace.getRoot().exists(prefix.append(string))) { 379 return IDEWorkbenchMessages.RenameResourceAction_nameExists; 380 } 381 return null; 382 } 383 }; 384 385 InputDialog dialog = new InputDialog(getShell(), 386 IDEWorkbenchMessages.RenameResourceAction_inputDialogTitle, 387 IDEWorkbenchMessages.RenameResourceAction_inputDialogMessage, 388 resource.getName(), validator); 389 dialog.setBlockOnOpen(true); 390 int result = dialog.open(); 391 if (result == Window.OK) 392 return dialog.getValue(); 393 return null; 394 } 395 396 404 private void queryNewResourceNameInline(final IResource resource) { 405 if (textEditorParent == null) { 408 createTextEditor(resource); 409 } 410 textEditor.setText(resource.getName()); 411 412 textEditorParent.setVisible(true); 414 Point textSize = textEditor.computeSize(SWT.DEFAULT, SWT.DEFAULT); 415 textSize.x += textSize.y; Point parentSize = textEditorParent.getSize(); 417 int inset = getCellEditorInset(textEditorParent); 418 textEditor.setBounds(2, inset, Math.min(textSize.x, parentSize.x - 4), 419 parentSize.y - 2 * inset); 420 textEditorParent.redraw(); 421 textEditor.selectAll(); 422 textEditor.setFocus(); 423 } 424 425 429 public void run() { 430 431 if (this.navigatorTree == null) { 432 IResource currentResource = getCurrentResource(); 433 if (currentResource == null || !currentResource.exists()) { 434 return; 435 } 436 if (!checkReadOnlyAndNull(currentResource)) { 438 return; 439 } 440 String newName = queryNewResourceName(currentResource); 441 if (newName == null || newName.equals("")) { return; 443 } 444 newPath = currentResource.getFullPath().removeLastSegments(1) 445 .append(newName); 446 super.run(); 447 } else { 448 runWithInlineEditor(); 449 } 450 } 451 452 456 private void runWithInlineEditor() { 457 IResource currentResource = getCurrentResource(); 458 if (!checkReadOnlyAndNull(currentResource)) { 459 return; 460 } 461 queryNewResourceNameInline(currentResource); 462 } 463 464 471 private IResource getCurrentResource() { 472 List resources = getSelectedResources(); 473 if (resources.size() == 1) { 474 return (IResource) resources.get(0); 475 } 476 return null; 477 478 } 479 480 486 protected void runWithNewPath(IPath path, IResource resource) { 487 this.newPath = path; 488 super.run(); 489 } 490 491 497 private void saveChangesAndDispose(IResource resource) { 498 if (saving == true) { 499 return; 500 } 501 502 saving = true; 503 inlinedResource = resource; 506 final String newName = textEditor.getText(); 507 Runnable query = new Runnable () { 513 public void run() { 514 try { 515 if (!newName.equals(inlinedResource.getName())) { 516 IWorkspace workspace = IDEWorkbenchPlugin 517 .getPluginWorkspace(); 518 IStatus status = workspace.validateName(newName, 519 inlinedResource.getType()); 520 if (!status.isOK()) { 521 displayError(status.getMessage()); 522 } else { 523 IPath newPath = inlinedResource.getFullPath() 524 .removeLastSegments(1).append(newName); 525 runWithNewPath(newPath, inlinedResource); 526 } 527 } 528 inlinedResource = null; 529 disposeTextWidget(); 531 if (navigatorTree != null && !navigatorTree.isDisposed()) { 535 navigatorTree.setFocus(); 536 } 537 } finally { 538 saving = false; 539 } 540 } 541 }; 542 getTree().getShell().getDisplay().asyncExec(query); 543 } 544 545 551 protected boolean updateSelection(IStructuredSelection selection) { 552 disposeTextWidget(); 553 554 if (selection.size() > 1) { 555 return false; 556 } 557 if (!super.updateSelection(selection)) { 558 return false; 559 } 560 561 IResource currentResource = getCurrentResource(); 562 if (currentResource == null || !currentResource.exists()) { 563 return false; 564 } 565 566 return true; 567 } 568 569 575 public void setTextActionHandler(TextActionHandler actionHandler) { 576 textActionHandler = actionHandler; 577 } 578 579 587 public String [] getModelProviderIds() { 588 return modelProviderIds; 589 } 590 591 601 public void setModelProviderIds(String [] modelProviderIds) { 602 this.modelProviderIds = modelProviderIds; 603 } 604 605 614 protected IRunnableWithProgress createOperation(final IStatus[] errorStatus) { 615 return new IRunnableWithProgress() { 616 public void run(IProgressMonitor monitor) { 617 IResource[] resources = (IResource[]) getActionResources() 618 .toArray(new IResource[getActionResources().size()]); 619 if (resources.length == 1) { 622 IWorkspaceRoot workspaceRoot = resources[0].getWorkspace() 624 .getRoot(); 625 IResource newResource = workspaceRoot.findMember(newPath); 626 boolean go = true; 627 if (newResource != null) { 628 go = checkOverwrite(getShell(), newResource); 629 } 630 if (go) { 631 MoveResourcesOperation op = new MoveResourcesOperation( 632 resources[0], 633 newPath, 634 IDEWorkbenchMessages.RenameResourceAction_operationTitle); 635 op.setModelProviderIds(getModelProviderIds()); 636 try { 637 PlatformUI 638 .getWorkbench() 639 .getOperationSupport() 640 .getOperationHistory() 641 .execute( 642 op, 643 monitor, 644 WorkspaceUndoUtil 645 .getUIInfoAdapter(getShell())); 646 } catch (ExecutionException e) { 647 if (e.getCause() instanceof CoreException) { 648 errorStatus[0] = ((CoreException) e.getCause()) 649 .getStatus(); 650 } else { 651 errorStatus[0] = new Status(IStatus.ERROR, 652 PlatformUI.PLUGIN_ID, 653 getProblemsMessage(), e); 654 } 655 } 656 } 657 } 658 } 659 }; 660 } 661 } 662 | Popular Tags |