1 19 20 package org.netbeans.modules.project.uiapi; 21 22 import java.awt.Component ; 23 import java.awt.Dialog ; 24 import java.awt.Window ; 25 import java.awt.event.ActionEvent ; 26 import java.awt.event.ActionListener ; 27 import java.awt.event.KeyEvent ; 28 import java.io.File ; 29 import java.io.IOException ; 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Collection ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import javax.swing.Action ; 36 import javax.swing.JButton ; 37 import javax.swing.JComponent ; 38 import javax.swing.JDialog ; 39 import javax.swing.KeyStroke ; 40 import javax.swing.SwingUtilities ; 41 import javax.swing.border.EmptyBorder ; 42 import javax.swing.event.ChangeEvent ; 43 import javax.swing.event.ChangeListener ; 44 import org.netbeans.api.progress.ProgressHandle; 45 import org.netbeans.api.progress.ProgressHandleFactory; 46 import org.netbeans.api.project.FileOwnerQuery; 47 import org.netbeans.api.project.Project; 48 import org.netbeans.api.project.ProjectManager; 49 import org.netbeans.api.project.ProjectUtils; 50 import org.netbeans.api.project.ui.OpenProjects; 51 import org.netbeans.spi.project.MoveOperationImplementation; 52 import org.netbeans.spi.project.support.ProjectOperations; 53 import org.netbeans.api.queries.VisibilityQuery; 54 import org.netbeans.spi.project.ui.support.CommonProjectActions; 55 import org.openide.DialogDescriptor; 56 import org.openide.DialogDisplayer; 57 import org.openide.ErrorManager; 58 import org.openide.LifecycleManager; 59 import org.openide.NotifyDescriptor; 60 import org.openide.awt.Mnemonics; 61 import org.openide.filesystems.FileObject; 62 import org.openide.filesystems.FileUtil; 63 import org.openide.util.ContextAwareAction; 64 import org.openide.util.Mutex; 65 import org.openide.util.NbBundle; 66 import org.openide.util.RequestProcessor; 67 import org.openide.util.lookup.Lookups; 68 69 72 public final class DefaultProjectOperationsImplementation { 73 74 private static final ErrorManager ERR = ErrorManager.getDefault(); 76 private static final double NOTIFY_WORK = 0.1; 79 private static final double FIND_PROJECT_WORK = 0.1; 80 static final int MAX_WORK = 100; 81 82 private DefaultProjectOperationsImplementation() { 83 } 84 85 private static String getDisplayName(Project project) { 86 return ProjectUtils.getInformation(project).getDisplayName(); 87 } 88 89 93 private static boolean performDelete(Project project, List <FileObject> toDelete, ProgressHandle handle) throws Exception { 94 try { 95 handle.start(toDelete.size() + 1 ); 96 97 int done = 0; 98 99 handle.progress(NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Progress_Cleaning_Project")); 100 101 ProjectOperations.notifyDeleting(project); 102 103 handle.progress(++done); 104 105 for (FileObject f : toDelete) { 106 handle.progress(NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Progress_Deleting_File", FileUtil.getFileDisplayName(f))); 107 108 if (f != null) 109 f.delete(); 110 111 handle.progress(++done); 112 } 113 114 FileObject projectFolder = project.getProjectDirectory(); 115 116 if (projectFolder.getChildren().length == 0) { 117 projectFolder.delete(); 119 } 120 121 handle.finish(); 122 123 ProjectOperations.notifyDeleted(project); 124 return true; 125 } catch (Exception e) { 126 String displayName = getDisplayName(project); 127 String message = NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Project_cannot_be_deleted.", displayName); 128 129 ErrorManager.getDefault().annotate(e, message); 130 131 return false; 132 } 133 } 134 135 public static void deleteProject(final Project project) { 136 deleteProject(project, new GUIUserInputHandler()); 137 } 138 139 static void deleteProject(final Project project, UserInputHandler handler) { 140 String displayName = getDisplayName(project); 141 FileObject projectFolder = project.getProjectDirectory(); 142 143 if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { 144 ERR.log(ErrorManager.INFORMATIONAL, "delete started: " + displayName); } 146 147 final List <FileObject> metadataFiles = ProjectOperations.getMetadataFiles(project); 148 final List <FileObject> dataFiles = ProjectOperations.getDataFiles(project); 149 final List <FileObject> allFiles = new ArrayList <FileObject>(); 150 151 allFiles.addAll(metadataFiles); 152 allFiles.addAll(dataFiles); 153 154 for (Iterator <FileObject> i = allFiles.iterator(); i.hasNext(); ) { 155 FileObject f = i.next(); 156 if (!FileUtil.isParentOf(projectFolder, f)) { 157 i.remove(); 158 } 159 } 160 161 final ProgressHandle handle = ProgressHandleFactory.createHandle(NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Delete_Project_Caption")); 162 final DefaultProjectDeletePanel deletePanel = new DefaultProjectDeletePanel(handle, displayName, FileUtil.getFileDisplayName(projectFolder), !dataFiles.isEmpty()); 163 164 String caption = NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Delete_Project_Caption"); 165 166 handler.showConfirmationDialog(deletePanel, project, caption, "Yes_Button", "No_Button", true, new Executor() { public void execute() throws Exception { 168 close(project); 169 170 if (deletePanel.isDeleteSources()) { 171 performDelete(project, allFiles, handle); 172 } else { 173 performDelete(project, metadataFiles, handle); 174 } 175 } 176 }); 177 178 if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { 179 ERR.log(ErrorManager.INFORMATIONAL, "delete done: " + displayName); } 181 } 182 183 static interface UserInputHandler { 184 void showConfirmationDialog(final JComponent panel, Project project, String caption, String confirmButton, String cancelButton, boolean doSetMessageType, final Executor executor); 185 } 186 187 private static final class GUIUserInputHandler implements UserInputHandler { 188 189 public void showConfirmationDialog(final JComponent panel, Project project, String caption, String confirmButton, String cancelButton, boolean doSetMessageType, final Executor executor) { 190 DefaultProjectOperationsImplementation.showConfirmationDialog(panel, project, caption, confirmButton, cancelButton, doSetMessageType, executor); 191 } 192 193 } 194 196 public static void copyProject(final Project project) { 198 final ProgressHandle handle = ProgressHandleFactory.createHandle(NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Copy_Project_Handle")); 199 final ProjectCopyPanel panel = new ProjectCopyPanel(handle, project, false); 200 handle.start(MAX_WORK); 202 203 showConfirmationDialog(panel, project, NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Copy_Project_Caption"), "Copy_Button", null, false, new Executor() { public void execute() throws Exception { 205 String nueName = panel.getNewName(); 206 File newTarget = FileUtil.normalizeFile(panel.getNewDirectory()); 207 208 FileObject newTargetFO = FileUtil.toFileObject(newTarget); 209 if (newTargetFO == null) { 210 newTargetFO = createFolder(newTarget.getParentFile(), newTarget.getName()); 211 } 212 doCopyProject(handle, project, nueName, newTargetFO); 213 } 214 }); 215 } 216 217 static void doCopyProject(ProgressHandle handle, Project project, String nueName, FileObject newTarget) throws Exception { 218 try { 219 int totalWork = MAX_WORK; 220 221 222 double currentWorkDone = 0; 223 224 handle.progress((int) currentWorkDone); 225 226 ProjectOperations.notifyCopying(project); 227 228 handle.progress((int) (currentWorkDone = totalWork * NOTIFY_WORK)); 229 230 FileObject target = newTarget.createFolder(nueName); 231 FileObject projectDirectory = project.getProjectDirectory(); 232 List <FileObject> toCopyList = Arrays.asList(projectDirectory.getChildren()); 233 234 double workPerFileAndOperation = totalWork * (1.0 - 2 * NOTIFY_WORK - FIND_PROJECT_WORK) / toCopyList.size(); 235 236 for (FileObject toCopy : toCopyList) { 237 doCopy(project, toCopy, target); 238 239 int lastWorkDone = (int) currentWorkDone; 240 241 currentWorkDone += workPerFileAndOperation; 242 243 if (lastWorkDone < (int) currentWorkDone) { 244 handle.progress((int) currentWorkDone); 245 } 246 } 247 248 ProjectManager.getDefault().clearNonProjectCache(); 250 Project nue = ProjectManager.getDefault().findProject(target); 251 252 assert nue != null; 253 254 handle.progress((int) (currentWorkDone += totalWork * FIND_PROJECT_WORK)); 255 256 ProjectOperations.notifyCopied(project, nue, FileUtil.toFile(project.getProjectDirectory()), nueName); 257 258 handle.progress((int) (currentWorkDone += totalWork * NOTIFY_WORK)); 259 260 ProjectManager.getDefault().saveProject(nue); 261 262 open(nue, false); 263 264 handle.progress(totalWork); 265 handle.finish(); 266 } catch (Exception e) { 267 ErrorManager.getDefault().annotate(e, NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ERR_Cannot_Move", e.getLocalizedMessage())); 268 throw e; 269 } 270 } 271 273 public static void moveProject(final Project project) { 275 final ProgressHandle handle = ProgressHandleFactory.createHandle(NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Move_Project_Handle")); 276 final ProjectCopyPanel panel = new ProjectCopyPanel(handle, project, true); 277 handle.start(MAX_WORK); 279 280 showConfirmationDialog(panel, project, NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Move_Project_Caption"), "Move_Button", null, false, new Executor() { public void execute() throws Exception { 282 String nueFolderName = panel.getProjectFolderName(); 283 String nueProjectName = panel.getNewName(); 284 File newTarget = FileUtil.normalizeFile(panel.getNewDirectory()); 285 286 FileObject newTargetFO = FileUtil.toFileObject(newTarget); 287 if (newTargetFO == null) { 288 newTargetFO = createFolder(newTarget.getParentFile(), newTarget.getName()); 289 } 290 291 292 doMoveProject(handle, project, nueFolderName, nueProjectName, newTargetFO, "ERR_Cannot_Move"); 293 } 294 }); 295 } 296 297 public static void renameProject(Project project) { 298 renameProject(project, null); 299 } 300 301 public static void renameProject(final Project project, final String nueName) { 302 final ProgressHandle handle = ProgressHandleFactory.createHandle(NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Rename_Project_Handle")); 303 final DefaultProjectRenamePanel panel = new DefaultProjectRenamePanel(handle, project, nueName); 304 305 handle.start(MAX_WORK); 307 308 showConfirmationDialog(panel, project, NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Rename_Project_Caption"), "Rename_Button", null, false, new Executor() { public void execute() throws Exception { 310 String nueName = panel.getNewName(); 311 312 if (panel.getRenameProjectFolder()) { 313 314 doMoveProject(handle, project, nueName, nueName, project.getProjectDirectory().getParent(), "ERR_Cannot_Rename"); 315 } else { 316 boolean originalOK = true; 317 Project main = OpenProjects.getDefault().getMainProject(); 318 boolean wasMain = main != null && project.getProjectDirectory().equals(main.getProjectDirectory()); 319 Project nue = null; 320 321 try { 322 handle.switchToIndeterminate(); 323 handle.switchToDeterminate(5); 324 325 int currentWorkDone = 0; 326 327 FileObject projectDirectory = project.getProjectDirectory(); 328 File projectDirectoryFile = FileUtil.toFile(project.getProjectDirectory()); 329 Collection <? extends MoveOperationImplementation> operations = project.getLookup().lookupAll(MoveOperationImplementation.class); 330 331 close(project); 332 333 handle.progress(++currentWorkDone); 334 335 for (MoveOperationImplementation o : operations) { 336 o.notifyMoving(); 337 } 338 339 handle.progress(++currentWorkDone); 340 341 for (MoveOperationImplementation o : operations) { 342 o.notifyMoved(null, projectDirectoryFile, nueName); 343 } 344 345 handle.progress(++currentWorkDone); 346 347 ProjectManager.getDefault().clearNonProjectCache(); 349 350 nue = ProjectManager.getDefault().findProject(projectDirectory); 351 352 assert nue != null; 353 354 originalOK = false; 355 356 handle.progress(++currentWorkDone); 357 358 operations = nue.getLookup().lookupAll(MoveOperationImplementation.class); 359 360 for (MoveOperationImplementation o : operations) { 361 o.notifyMoved(project, projectDirectoryFile, nueName); 362 } 363 364 ProjectManager.getDefault().saveProject(nue); 365 366 open(nue, wasMain); 367 368 handle.progress(++currentWorkDone); 369 370 handle.finish(); 371 } catch (Exception e) { 372 if (originalOK) { 373 open(project, wasMain); 374 } else { 375 assert nue != null; 376 open(nue, wasMain); 377 } 378 ErrorManager.getDefault().annotate(e, NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ERR_Cannot_Rename", e.getLocalizedMessage())); 379 throw e; 380 } 381 } 382 } 383 }); 384 } 385 386 static void doMoveProject(ProgressHandle handle, Project project, String nueFolderName, String nueProjectName, FileObject newTarget, String errorKey) throws Exception { 387 boolean originalOK = true; 388 Project main = OpenProjects.getDefault().getMainProject(); 389 boolean wasMain = main != null && project.getProjectDirectory().equals(main.getProjectDirectory()); 390 FileObject target = null; 391 392 try { 393 394 int totalWork = MAX_WORK; 395 double currentWorkDone = 0; 396 397 handle.progress((int) currentWorkDone); 398 399 ProjectOperations.notifyMoving(project); 400 401 close(project); 402 403 handle.progress((int) (currentWorkDone = totalWork * NOTIFY_WORK)); 404 405 FileObject projectDirectory = project.getProjectDirectory(); 406 List <FileObject> toMoveList = Arrays.asList(projectDirectory.getChildren()); 407 408 double workPerFileAndOperation = (totalWork * (1.0 - 2 * NOTIFY_WORK - FIND_PROJECT_WORK) / toMoveList.size()) / 2; 409 410 target = newTarget.createFolder(nueFolderName); 411 412 for (FileObject toCopy : toMoveList) { 413 doCopy(project, toCopy, target); 414 415 int lastWorkDone = (int) currentWorkDone; 416 417 currentWorkDone += workPerFileAndOperation; 418 419 if (lastWorkDone < (int) currentWorkDone) { 420 handle.progress((int) currentWorkDone); 421 } 422 } 423 424 originalOK = false; 425 426 for (FileObject toCopy : toMoveList) { 427 doDelete(project, toCopy); 428 429 int lastWorkDone = (int) currentWorkDone; 430 431 currentWorkDone += workPerFileAndOperation; 432 433 if (lastWorkDone < (int) currentWorkDone) { 434 handle.progress((int) currentWorkDone); 435 } 436 } 437 438 if (projectDirectory.getChildren().length == 0) { 439 projectDirectory.delete(); 440 } 441 442 ProjectManager.getDefault().clearNonProjectCache(); 444 Project nue = ProjectManager.getDefault().findProject(target); 445 446 handle.progress((int) (currentWorkDone += totalWork * FIND_PROJECT_WORK)); 447 448 assert nue != null; 449 450 ProjectOperations.notifyMoved(project, nue, FileUtil.toFile(project.getProjectDirectory()), nueProjectName); 451 452 handle.progress((int) (currentWorkDone += totalWork * NOTIFY_WORK)); 453 454 ProjectManager.getDefault().saveProject(nue); 455 456 open(nue, wasMain); 457 458 handle.progress(totalWork); 459 handle.finish(); 460 } catch (Exception e) { 461 if (originalOK) { 462 open(project, wasMain); 463 } else { 464 assert target != null; 465 466 ProjectManager.getDefault().clearNonProjectCache(); 468 Project nue = ProjectManager.getDefault().findProject(target); 469 470 assert nue != null; 471 472 open(nue, wasMain); 473 } 474 ErrorManager.getDefault().annotate(e, NbBundle.getMessage(DefaultProjectOperationsImplementation.class, errorKey, e.getLocalizedMessage())); 475 throw e; 476 } 477 } 478 480 private static void doCopy(Project original, FileObject from, FileObject toParent) throws IOException { 482 if (!VisibilityQuery.getDefault().isVisible(from)) { 483 return ; 485 } 486 487 if (!original.getProjectDirectory().equals(FileOwnerQuery.getOwner(from).getProjectDirectory())) { 488 return ; 489 } 490 491 if (from.isFolder()) { 492 FileObject copy = toParent.createFolder(from.getNameExt()); 493 for (FileObject kid : from.getChildren()) { 494 doCopy(original, kid, copy); 495 } 496 } else { 497 assert from.isData(); 498 FileObject target = FileUtil.copyFile(from, toParent, from.getName(), from.getExt()); 499 } 500 } 501 502 private static FileObject createFolder(File parent, String name) throws IOException { 503 FileObject path = FileUtil.toFileObject(parent); 504 if (path != null) { 505 return path.createFolder(name); 506 } else { 507 return createFolder(parent.getParentFile(), parent.getName()).createFolder(name); 508 } 509 } 510 511 private static boolean doDelete(Project original, FileObject toDelete) throws IOException { 512 if (!original.getProjectDirectory().equals(FileOwnerQuery.getOwner(toDelete).getProjectDirectory())) { 513 return false; 514 } 515 516 if (toDelete.isFolder()) { 517 boolean delete = true; 518 519 for (FileObject kid : toDelete.getChildren()) { 520 delete &= doDelete(original, kid); 521 } 522 523 if (delete) { 524 toDelete.delete(); 525 } 526 527 return delete; 528 } else { 529 assert toDelete.isData(); 530 toDelete.delete(); 531 return true; 532 } 533 } 534 535 private static JComponent wrapPanel(JComponent component) { 536 component.setBorder(new EmptyBorder (12, 12, 12, 12)); 537 538 return component; 539 } 540 541 private static void showConfirmationDialog(final JComponent panel, Project project, String caption, String confirmButton, String cancelButton, boolean doSetMessageType, final Executor executor) { 542 final JButton confirm = new JButton (); 543 Mnemonics.setLocalizedText(confirm, NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_" + confirmButton)); 544 final JButton cancel = new JButton (cancelButton == null ? 545 NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_Cancel_Button") 546 : NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "LBL_" + cancelButton)); 547 548 confirm.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ACSD_" + confirmButton)); 549 cancel.getAccessibleContext().setAccessibleDescription(cancelButton == null ? 550 NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ACSD_Cancel_Button") 551 : NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ACSD_" + cancelButton)); 552 553 assert panel instanceof InvalidablePanel; 554 555 ((InvalidablePanel) panel).addChangeListener(new ChangeListener () { 556 public void stateChanged(ChangeEvent e) { 557 confirm.setEnabled(((InvalidablePanel) panel).isPanelValid()); 558 } 559 }); 560 561 confirm.setEnabled(((InvalidablePanel) panel).isPanelValid()); 562 563 final Dialog [] dialog = new Dialog [1]; 564 565 DialogDescriptor dd = new DialogDescriptor(doSetMessageType ? panel : wrapPanel(panel), caption, true, new Object [] {confirm, cancel}, cancelButton != null ? cancel : confirm, DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener () { 566 private boolean operationRunning; 567 public void actionPerformed(ActionEvent e) { 568 if (operationRunning) { 570 return ; 571 } 572 573 if (dialog[0] instanceof JDialog ) { 574 ((JDialog ) dialog[0]).getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).remove(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); 575 ((JDialog ) dialog[0]).setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 576 } 577 578 operationRunning = true; 579 580 if (e.getSource() == confirm) { 581 confirm.setEnabled(false); 582 cancel.setEnabled(false); 583 ((InvalidablePanel) panel).showProgress(); 584 585 Component findParent = panel; 586 587 while (findParent != null && !(findParent instanceof Window )) { 588 findParent = findParent.getParent(); 589 } 590 591 if (findParent != null) { 592 ((Window ) findParent).pack(); 593 } 594 595 RequestProcessor.getDefault().post(new Runnable () { 596 public void run() { 597 Exception e = null; 598 599 try { 600 executor.execute(); 601 } catch (Exception ex) { 602 e = ex; 603 } 604 605 final Exception ex = e; 606 607 SwingUtilities.invokeLater(new Runnable () { 608 public void run() { 609 dialog[0].setVisible(false); 610 611 if (ex != null) { 612 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 613 ErrorManager.getDefault().notify(ErrorManager.USER, ex); 614 } 615 } 616 }); 617 } 618 }); 619 } else { 620 dialog[0].setVisible(false); 621 } 622 } 623 }); 624 625 if (doSetMessageType) { 626 dd.setMessageType(NotifyDescriptor.QUESTION_MESSAGE); 627 } 628 629 dd.setClosingOptions(new Object [0]); 630 631 dialog[0] = DialogDisplayer.getDefault().createDialog(dd); 632 633 dialog[0].setVisible(true); 634 635 dialog[0].dispose(); 636 dialog[0] = null; 637 } 638 639 static String computeError(File location, String projectNameText, boolean pureRename) { 640 return computeError(location, projectNameText, null, pureRename); 641 } 642 643 static String computeError(File location, String projectNameText, String projectFolderText, boolean pureRename) { 644 File parent = location; 645 if (!location.exists()) { 646 parent = location.getParentFile(); 648 while (parent != null && !parent.exists()) { 649 parent = parent.getParentFile(); 650 } 651 if (parent == null) { 652 return NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ERR_Location_Does_Not_Exist"); 653 } 654 } 655 656 if (!parent.canWrite()) { 657 return NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ERR_Location_Read_Only"); 658 } 659 660 if (projectNameText.length() == 0) { 661 return NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ERR_Project_Name_Must_Entered"); 662 } 663 664 File projectFolderFile = null; 665 if (projectFolderText == null) { 666 projectFolderFile = new File (location, projectNameText); 667 } else { 668 projectFolderFile = new File (projectFolderText); 669 } 670 671 if (projectFolderFile.exists() && !pureRename) { 672 return NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ERR_Project_Folder_Exists"); 673 } 674 675 if (projectNameText.indexOf('/') != -1 || projectNameText.indexOf('\\') != -1) { 676 return NbBundle.getMessage(DefaultProjectOperationsImplementation.class, "ERR_Not_Valid_Filename", projectNameText); 677 } 678 679 return null; 680 } 681 682 private static void close(final Project prj) { 683 Mutex.EVENT.readAccess(new Mutex.Action<Void >() { 684 public Void run() { 685 LifecycleManager.getDefault().saveAll(); 686 687 Action closeAction = CommonProjectActions.closeProjectAction(); 688 closeAction = closeAction instanceof ContextAwareAction ? ((ContextAwareAction) closeAction).createContextAwareInstance(Lookups.fixed(prj)) : null; 689 690 if (closeAction != null && closeAction.isEnabled()) { 691 closeAction.actionPerformed(new ActionEvent (prj, -1, "")); } else { 693 OpenProjects.getDefault().close(new Project[] {prj}); 695 } 696 697 return null; 698 } 699 }); 700 } 701 702 private static void open(final Project prj, final boolean setAsMain) { 703 Mutex.EVENT.readAccess(new Runnable () { 704 public void run() { 705 OpenProjects.getDefault().open(new Project[] {prj}, false); 706 if (setAsMain) { 707 OpenProjects.getDefault().setMainProject(prj); 708 } 709 } 710 }); 711 } 712 713 static interface Executor { 714 public void execute() throws Exception ; 715 } 716 717 public static interface InvalidablePanel { 718 public void addChangeListener(ChangeListener l); 719 public void removeChangeListener(ChangeListener l); 720 public boolean isPanelValid(); 721 public void showProgress(); 722 } 723 725 } 726 | Popular Tags |