1 19 20 package org.netbeans.modules.merge.builtin.visualizer; 21 22 import java.awt.Component ; 23 import java.awt.Dimension ; 24 import java.awt.Point ; 25 import java.awt.Rectangle ; 26 import java.awt.Toolkit ; 27 import java.beans.PropertyChangeEvent ; 28 import java.beans.PropertyChangeListener ; 29 import java.beans.PropertyVetoException ; 30 import java.io.IOException ; 31 import java.lang.ref.Reference ; 32 import java.lang.ref.WeakReference ; 33 import java.util.ArrayList ; 34 import java.util.HashMap ; 35 import java.util.Iterator ; 36 import java.util.Map ; 37 import javax.swing.JPopupMenu ; 38 import javax.swing.SwingUtilities ; 39 import javax.swing.event.ChangeListener ; 40 import javax.swing.plaf.TabbedPaneUI ; 41 import org.openide.DialogDisplayer; 42 import org.openide.ErrorManager; 43 44 import org.openide.NotifyDescriptor; 45 import org.openide.actions.FileSystemAction; 46 import org.openide.awt.MouseUtils; 47 import org.openide.awt.JPopupMenuPlus; 48 import org.openide.cookies.CloseCookie; 49 import org.openide.cookies.SaveCookie; 50 import org.openide.nodes.Node; 51 import org.openide.windows.TopComponent; 52 import org.openide.windows.Workspace; 53 import org.openide.util.*; 54 import org.openide.util.actions.CallableSystemAction; 55 import org.openide.util.actions.SystemAction; 56 import org.openide.windows.WindowManager; 57 import org.netbeans.api.javahelp.Help; 58 59 65 public class MergeDialogComponent extends TopComponent implements ChangeListener { 66 67 public static final String PROP_PANEL_CLOSING = "panelClosing"; public static final String PROP_ALL_CLOSED = "allPanelsClosed"; public static final String PROP_ALL_CANCELLED = "allPanelsCancelled"; public static final String PROP_PANEL_SAVE = "panelSave"; 72 private Map <MergePanel, MergeNode> nodesForPanels = new HashMap <MergePanel, MergeNode>(); 73 74 75 public MergeDialogComponent() { 76 initComponents(); 77 initListeners(); 78 putClientProperty("PersistenceType", "Never"); 79 setName(org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "MergeDialogComponent.title")); 80 getAccessibleContext().setAccessibleName(NbBundle.getMessage(MergeDialogComponent.class, "ACSN_Merge_Dialog_Component")); getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(MergeDialogComponent.class, "ACSD_Merge_Dialog_Component")); mergeTabbedPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(MergeDialogComponent.class, "ACSN_Merge_Tabbed_Pane")); mergeTabbedPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(MergeDialogComponent.class, "ACSD_Merge_Tabbed_Pane")); } 85 86 public HelpCtx getHelpCtx() { 87 return new HelpCtx(MergeDialogComponent.class); 88 } 89 90 95 private void initComponents() { 97 java.awt.GridBagConstraints gridBagConstraints; 98 99 mergeTabbedPane = new javax.swing.JTabbedPane (); 100 buttonsPanel = new javax.swing.JPanel (); 101 okButton = new javax.swing.JButton (); 102 cancelButton = new javax.swing.JButton (); 103 helpButton = new javax.swing.JButton (); 104 105 FormListener formListener = new FormListener(); 106 107 setLayout(new java.awt.GridBagLayout ()); 108 109 mergeTabbedPane.setTabPlacement(javax.swing.JTabbedPane.BOTTOM); 110 mergeTabbedPane.setPreferredSize(new java.awt.Dimension (600, 600)); 111 gridBagConstraints = new java.awt.GridBagConstraints (); 112 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 113 gridBagConstraints.weightx = 1.0; 114 gridBagConstraints.weighty = 1.0; 115 add(mergeTabbedPane, gridBagConstraints); 116 117 buttonsPanel.setLayout(new java.awt.GridBagLayout ()); 118 119 org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "BTN_OK")); okButton.setToolTipText(org.openide.util.NbBundle.getBundle(MergeDialogComponent.class).getString("ACS_BTN_OKA11yDesc")); okButton.addActionListener(formListener); 122 gridBagConstraints = new java.awt.GridBagConstraints (); 123 gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; 124 gridBagConstraints.weightx = 1.0; 125 gridBagConstraints.insets = new java.awt.Insets (0, 5, 0, 0); 126 buttonsPanel.add(okButton, gridBagConstraints); 127 128 org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "BTN_Cancel")); cancelButton.setToolTipText(org.openide.util.NbBundle.getBundle(MergeDialogComponent.class).getString("ACS_BTN_CancelA11yDesc")); cancelButton.addActionListener(formListener); 131 gridBagConstraints = new java.awt.GridBagConstraints (); 132 gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; 133 gridBagConstraints.insets = new java.awt.Insets (0, 5, 0, 0); 134 buttonsPanel.add(cancelButton, gridBagConstraints); 135 136 org.openide.awt.Mnemonics.setLocalizedText(helpButton, org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "BTN_Help")); helpButton.setToolTipText(org.openide.util.NbBundle.getBundle(MergeDialogComponent.class).getString("ACS_BTN_HelpA11yDesc")); helpButton.addActionListener(formListener); 139 gridBagConstraints = new java.awt.GridBagConstraints (); 140 gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; 141 gridBagConstraints.insets = new java.awt.Insets (0, 5, 0, 0); 142 buttonsPanel.add(helpButton, gridBagConstraints); 143 144 gridBagConstraints = new java.awt.GridBagConstraints (); 145 gridBagConstraints.gridy = 1; 146 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 147 gridBagConstraints.weightx = 1.0; 148 gridBagConstraints.insets = new java.awt.Insets (12, 12, 11, 11); 149 add(buttonsPanel, gridBagConstraints); 150 } 151 152 154 private class FormListener implements java.awt.event.ActionListener { 155 FormListener() {} 156 public void actionPerformed(java.awt.event.ActionEvent evt) { 157 if (evt.getSource() == okButton) { 158 MergeDialogComponent.this.okButtonActionPerformed(evt); 159 } 160 else if (evt.getSource() == cancelButton) { 161 MergeDialogComponent.this.cancelButtonActionPerformed(evt); 162 } 163 else if (evt.getSource() == helpButton) { 164 MergeDialogComponent.this.helpButtonActionPerformed(evt); 165 } 166 } 167 } 169 private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { Component [] panels; 173 synchronized (this) { 174 panels = mergeTabbedPane.getComponents(); 175 } 176 boolean warning = false; 177 ArrayList <String > unsavedPanelNames = new ArrayList <String >(); 178 ArrayList <SaveCookie> saveCookies = new ArrayList <SaveCookie>(); 179 for (int i = 0; i < panels.length; i++) { 180 MergePanel panel = (MergePanel) panels[i]; 181 if((panel.getNumUnresolvedConflicts() > 0) && (!warning)) 182 warning = true; 183 MergeNode node = nodesForPanels.get(panel); 184 SaveCookie sc; 185 if ((sc = node.getCookie(SaveCookie.class)) != null) { 186 unsavedPanelNames.add(panel.getName()); 187 saveCookies.add(sc); 188 } 189 } 190 Object ret; 191 if (unsavedPanelNames.size() == 1) { 193 ret = DialogDisplayer.getDefault().notify( 194 new NotifyDescriptor.Confirmation((warning)?NbBundle.getMessage(MergeDialogComponent.class,"SaveFileWarningQuestion",unsavedPanelNames.get(0)): 195 NbBundle.getMessage(MergeDialogComponent.class,"SaveFileQuestion",unsavedPanelNames.get(0)), 196 NotifyDescriptor.YES_NO_CANCEL_OPTION)); 197 } else if (unsavedPanelNames.size() > 1) { 198 ret = DialogDisplayer.getDefault().notify( 199 new NotifyDescriptor.Confirmation((warning)?NbBundle.getMessage(MergeDialogComponent.class,"SaveFilesWarningQuestion",new Integer (unsavedPanelNames.size())): 200 NbBundle.getMessage(MergeDialogComponent.class,"SaveFilesQuestion",new Integer (unsavedPanelNames.size())), 201 NotifyDescriptor.YES_NO_CANCEL_OPTION)); 202 } else { 203 if(warning){ 204 ret = DialogDisplayer.getDefault().notify( 205 new NotifyDescriptor.Confirmation(NbBundle.getMessage(MergeDialogComponent.class,"WarningQuestion",new Integer (unsavedPanelNames.size())), 206 NotifyDescriptor.OK_CANCEL_OPTION)); 207 if(ret.equals(NotifyDescriptor.NO_OPTION)) 208 return; 209 }else 210 ret = NotifyDescriptor.YES_OPTION; 211 } 212 if (!NotifyDescriptor.YES_OPTION.equals(ret) && !NotifyDescriptor.NO_OPTION.equals(ret)) return ; 213 if (NotifyDescriptor.YES_OPTION.equals(ret) || NotifyDescriptor.OK_OPTION.equals(ret)) { 214 for (SaveCookie sc: saveCookies) { 215 IOException ioException = null; 216 try { 217 sc.save(); 218 } catch (UserQuestionException uqex) { 219 Object status = DialogDisplayer.getDefault().notify( 220 new NotifyDescriptor.Confirmation(uqex.getLocalizedMessage())); 221 if (status == NotifyDescriptor.OK_OPTION || status == NotifyDescriptor.YES_OPTION) { 222 boolean success; 223 try { 224 uqex.confirmed(); 225 success = true; 226 } catch (IOException ioex) { 227 success = false; 228 ioException = ioex; 229 } 230 if (success) { 231 try { 232 sc.save(); 233 } catch (IOException ioex) { 234 ioException = ioex; 235 } 236 } 237 } else if (status != NotifyDescriptor.NO_OPTION) { 238 return ; 240 } 241 } catch (IOException ioEx) { 242 ioException = ioEx; 243 } 244 if (ioException != null) { 245 ErrorManager.getDefault().notify(ioException); 246 return ; 248 } 249 } 250 } 251 for (int i = 0; i < panels.length; i++) { 252 MergePanel panel = (MergePanel) panels[i]; 253 try { 254 fireVetoableChange(PROP_PANEL_CLOSING, null, panel); 255 } catch (PropertyVetoException pvex) { 256 return ; 257 } 258 removeMergePanel(panel); 259 } 260 } 262 private void helpButtonActionPerformed(java.awt.event.ActionEvent evt) { Help help = (Help) Lookup.getDefault().lookup(Help.class); 264 help.showHelp(getHelpCtx()); 265 } 267 private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) { synchronized (this) { 270 try { 271 fireVetoableChange(PROP_ALL_CANCELLED, null, null); 272 } catch (PropertyVetoException pvex) {} 273 close(); 274 } 275 } 277 protected void componentClosed() { 278 Component [] panels; 279 synchronized (this) { 280 try { 281 fireVetoableChange(PROP_ALL_CANCELLED, null, null); 282 } catch (PropertyVetoException pvex) {} 283 284 panels = mergeTabbedPane.getComponents(); 285 } 286 for (int i = 0; i < panels.length; i++) { 287 MergePanel panel = (MergePanel) panels[i]; 288 removeMergePanel(panel); 289 } 290 } 291 292 293 public Dimension getPreferredSize() { 294 Rectangle bounds = WindowManager.getDefault().getCurrentWorkspace().getBounds(); 295 return new Dimension (bounds.width / 2, (int) (bounds.height / 1.25)); 296 } 297 298 public int getPersistenceType() { 299 return TopComponent.PERSISTENCE_NEVER; 300 } 301 302 private javax.swing.JPanel buttonsPanel; 304 private javax.swing.JButton cancelButton; 305 private javax.swing.JButton helpButton; 306 private javax.swing.JTabbedPane mergeTabbedPane; 307 private javax.swing.JButton okButton; 308 310 public void addNotify() { 311 super.addNotify(); 312 javax.swing.JRootPane root = getRootPane(); 313 if (root != null) root.setDefaultButton(okButton); 314 322 } 323 324 private void initListeners() { 325 mergeTabbedPane.addMouseListener(new PopupMenuImpl()); 326 mergeTabbedPane.addChangeListener(this); 327 } 328 329 public void open(Workspace workspace) { 330 super.open(workspace); 331 requestActive(); 332 } 333 334 public synchronized void addMergePanel(MergePanel panel) { 335 mergeTabbedPane.addTab(panel.getName(), panel); 336 MergeNode node = new MergeNode(panel); 337 nodesForPanels.put(panel, node); 338 mergeTabbedPane.setSelectedComponent(panel); 339 setActivatedNodes(new Node[] { node }); 340 } 341 342 public synchronized void removeMergePanel(MergePanel panel) { 343 mergeTabbedPane.remove(panel); 344 nodesForPanels.remove(panel); 345 if (mergeTabbedPane.getTabCount() == 0) { 346 try { 347 fireVetoableChange(PROP_ALL_CLOSED, null, null); 348 } catch (PropertyVetoException pvex) { 349 return ; 350 } 351 close(); 352 } 353 } 354 355 public MergePanel getSelectedMergePanel() { 356 Component selected = mergeTabbedPane.getSelectedComponent(); 357 if (selected == null || !(selected instanceof MergePanel)) return null; 358 return ((MergePanel) selected); 359 } 360 361 private static JPopupMenu createPopupMenu(MergePanel panel) { 362 JPopupMenu popup = new JPopupMenuPlus(); 363 SystemAction[] actions = panel.getSystemActions(); 364 for (int i = 0; i < actions.length; i++) { 365 if (actions[i] == null) { 366 popup.addSeparator(); 367 } else if (actions[i] instanceof CallableSystemAction) { 368 popup.add(((CallableSystemAction)actions[i]).getPopupPresenter()); 369 } else if (actions[i] instanceof FileSystemAction) { 371 popup.add(((FileSystemAction)actions[i]).getPopupPresenter()); 372 } 373 } 374 return popup; 375 } 376 377 381 private static void showPopupMenu(JPopupMenu popup, Point p, Component comp) { 382 SwingUtilities.convertPointToScreen(p, comp); 383 Dimension popupSize = popup.getPreferredSize(); 384 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 385 386 if (p.x + popupSize.width > screenSize.width) { 387 p.x = screenSize.width - popupSize.width; 388 } 389 if (p.y + popupSize.height > screenSize.height) { 390 p.y = screenSize.height - popupSize.height; 391 } 392 SwingUtilities.convertPointFromScreen(p, comp); 393 popup.show(comp, p.x, p.y); 394 } 395 396 397 public void stateChanged(javax.swing.event.ChangeEvent changeEvent) { 398 MergePanel panel = (MergePanel) mergeTabbedPane.getSelectedComponent(); 399 if (panel != null) { 400 Node node = nodesForPanels.get(panel); 401 if (node != null) { 402 setActivatedNodes(new Node[] { node }); 403 } 404 } 405 } 406 407 408 private class PopupMenuImpl extends MouseUtils.PopupMouseAdapter { 409 public PopupMenuImpl () {} 410 411 413 protected void showPopup(java.awt.event.MouseEvent mouseEvent) { 414 TabbedPaneUI tabUI = mergeTabbedPane.getUI(); 415 int clickTab = tabUI.tabForCoordinate(mergeTabbedPane, mouseEvent.getX(), mouseEvent.getY()); 416 MergePanel panel = getSelectedMergePanel(); 417 if (panel == null) { 418 return; 419 } 420 if (clickTab != -1) { 421 showPopupMenu(createPopupMenu(panel), mouseEvent.getPoint(), mergeTabbedPane); 423 } 424 } 425 426 } 427 428 private class MergeNode extends org.openide.nodes.AbstractNode implements PropertyChangeListener , SaveCookie { 429 430 private Reference <MergePanel> mergePanelRef; 431 432 public MergeNode(MergePanel panel) { 433 super(org.openide.nodes.Children.LEAF); 434 panel.addPropertyChangeListener(WeakListeners.propertyChange(this, panel)); 435 mergePanelRef = new WeakReference <MergePanel>(panel); 436 getCookieSet().add(new CloseCookieImpl()); 437 } 439 440 private void activateSave() { 441 getCookieSet().add(this); 442 } 443 444 private void deactivateSave() { 445 getCookieSet().remove(this); 446 } 447 448 public void propertyChange(PropertyChangeEvent propertyChangeEvent) { 449 if (MergePanel.PROP_CAN_BE_SAVED.equals(propertyChangeEvent.getPropertyName())) { 450 activateSave(); 451 } else if (MergePanel.PROP_CAN_NOT_BE_SAVED.equals(propertyChangeEvent.getPropertyName())) { 452 deactivateSave(); 453 } 454 } 455 456 public void save() throws java.io.IOException { 457 try { 458 MergeDialogComponent.this.fireVetoableChange(PROP_PANEL_SAVE, null, mergePanelRef.get()); 459 } catch (PropertyVetoException vetoEx) { 460 Throwable cause = vetoEx.getCause(); 461 if (cause instanceof IOException ) { 462 throw (IOException ) cause; 463 } else { 464 throw new java.io.IOException (vetoEx.getLocalizedMessage()); 465 } 466 } 467 } 470 471 private class CloseCookieImpl extends Object implements CloseCookie { 472 public CloseCookieImpl () {} 473 474 public boolean close() { 475 try { 476 MergeDialogComponent.this.fireVetoableChange(PROP_PANEL_CLOSING, null, mergePanelRef.get()); 477 } catch (PropertyVetoException vetoEx) { 478 return false; 479 } 480 removeMergePanel(mergePanelRef.get()); 481 return true; 482 } 483 } 484 485 } 486 } 487 | Popular Tags |