~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to diff/src/org/netbeans/modules/merge/builtin/visualizer/MergeDialogComponent.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
 
 
42
package org.netbeans.modules.merge.builtin.visualizer;
 
43
 
 
44
import java.awt.Component;
 
45
import java.awt.Dimension;
 
46
import java.awt.Point;
 
47
import java.awt.Rectangle;
 
48
import java.awt.Toolkit;
 
49
import java.beans.PropertyChangeEvent;
 
50
import java.beans.PropertyChangeListener;
 
51
import java.beans.PropertyVetoException;
 
52
import java.io.IOException;
 
53
import java.lang.ref.Reference;
 
54
import java.lang.ref.WeakReference;
 
55
import java.util.ArrayList;
 
56
import java.util.HashMap;
 
57
import java.util.Iterator;
 
58
import java.util.Map;
 
59
import javax.swing.JPopupMenu;
 
60
import javax.swing.SwingUtilities;
 
61
import javax.swing.event.ChangeListener;
 
62
import javax.swing.plaf.TabbedPaneUI;
 
63
import org.openide.DialogDisplayer;
 
64
import org.openide.ErrorManager;
 
65
 
 
66
import org.openide.NotifyDescriptor;
 
67
import org.openide.actions.FileSystemAction;
 
68
import org.openide.awt.MouseUtils;
 
69
import org.openide.awt.JPopupMenuPlus;
 
70
import org.openide.cookies.CloseCookie;
 
71
import org.openide.cookies.SaveCookie;
 
72
import org.openide.nodes.Node;
 
73
import org.openide.windows.TopComponent;
 
74
import org.openide.windows.Workspace;
 
75
import org.openide.util.*;
 
76
import org.openide.util.actions.CallableSystemAction;
 
77
import org.openide.util.actions.SystemAction;
 
78
import org.openide.windows.WindowManager;
 
79
import org.netbeans.api.javahelp.Help;
 
80
 
 
81
/**
 
82
 * This is a component, that acts as a non modal dialog.
 
83
 * There are problems with accessibility to non-modal dialogs,
 
84
 * therefore this approach was chosen.
 
85
 * @author  Martin Entlicher
 
86
 */
 
87
public class MergeDialogComponent extends TopComponent implements ChangeListener {
 
88
    
 
89
    public static final String PROP_PANEL_CLOSING = "panelClosing"; // NOI18N
 
90
    public static final String PROP_ALL_CLOSED = "allPanelsClosed"; // NOI18N
 
91
    public static final String PROP_ALL_CANCELLED = "allPanelsCancelled"; // NOI18N
 
92
    public static final String PROP_PANEL_SAVE = "panelSave"; // NOI18N
 
93
    
 
94
    private Map<MergePanel, MergeNode> nodesForPanels = new HashMap<MergePanel, MergeNode>();
 
95
    
 
96
    /** Creates new form MergeDialogComponent */
 
97
    public MergeDialogComponent() {
 
98
        initComponents();
 
99
        initListeners();
 
100
        putClientProperty("PersistenceType", "Never");
 
101
        setName(org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "MergeDialogComponent.title"));
 
102
        getAccessibleContext().setAccessibleName(NbBundle.getMessage(MergeDialogComponent.class, "ACSN_Merge_Dialog_Component")); // NOI18N
 
103
        getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(MergeDialogComponent.class, "ACSD_Merge_Dialog_Component")); // NOI18N
 
104
        mergeTabbedPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(MergeDialogComponent.class, "ACSN_Merge_Tabbed_Pane")); // NOI18N
 
105
        mergeTabbedPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(MergeDialogComponent.class, "ACSD_Merge_Tabbed_Pane")); // NOI18N
 
106
    }
 
107
    
 
108
    public HelpCtx getHelpCtx() {
 
109
        return new HelpCtx(MergeDialogComponent.class);
 
110
    }
 
111
    
 
112
    /** This method is called from within the constructor to
 
113
     * initialize the form.
 
114
     * WARNING: Do NOT modify this code. The content of this method is
 
115
     * always regenerated by the Form Editor.
 
116
     */
 
117
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
 
118
    private void initComponents() {
 
119
        java.awt.GridBagConstraints gridBagConstraints;
 
120
 
 
121
        mergeTabbedPane = new javax.swing.JTabbedPane();
 
122
        buttonsPanel = new javax.swing.JPanel();
 
123
        okButton = new javax.swing.JButton();
 
124
        cancelButton = new javax.swing.JButton();
 
125
        helpButton = new javax.swing.JButton();
 
126
 
 
127
        FormListener formListener = new FormListener();
 
128
 
 
129
        setLayout(new java.awt.GridBagLayout());
 
130
 
 
131
        mergeTabbedPane.setTabPlacement(javax.swing.JTabbedPane.BOTTOM);
 
132
        mergeTabbedPane.setPreferredSize(new java.awt.Dimension(600, 600));
 
133
        gridBagConstraints = new java.awt.GridBagConstraints();
 
134
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
 
135
        gridBagConstraints.weightx = 1.0;
 
136
        gridBagConstraints.weighty = 1.0;
 
137
        add(mergeTabbedPane, gridBagConstraints);
 
138
 
 
139
        buttonsPanel.setLayout(new java.awt.GridBagLayout());
 
140
 
 
141
        org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "BTN_OK")); // NOI18N
 
142
        okButton.setToolTipText(org.openide.util.NbBundle.getBundle(MergeDialogComponent.class).getString("ACS_BTN_OKA11yDesc")); // NOI18N
 
143
        okButton.addActionListener(formListener);
 
144
        gridBagConstraints = new java.awt.GridBagConstraints();
 
145
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
 
146
        gridBagConstraints.weightx = 1.0;
 
147
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
 
148
        buttonsPanel.add(okButton, gridBagConstraints);
 
149
 
 
150
        org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "BTN_Cancel")); // NOI18N
 
151
        cancelButton.setToolTipText(org.openide.util.NbBundle.getBundle(MergeDialogComponent.class).getString("ACS_BTN_CancelA11yDesc")); // NOI18N
 
152
        cancelButton.addActionListener(formListener);
 
153
        gridBagConstraints = new java.awt.GridBagConstraints();
 
154
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
 
155
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
 
156
        buttonsPanel.add(cancelButton, gridBagConstraints);
 
157
 
 
158
        org.openide.awt.Mnemonics.setLocalizedText(helpButton, org.openide.util.NbBundle.getMessage(MergeDialogComponent.class, "BTN_Help")); // NOI18N
 
159
        helpButton.setToolTipText(org.openide.util.NbBundle.getBundle(MergeDialogComponent.class).getString("ACS_BTN_HelpA11yDesc")); // NOI18N
 
160
        helpButton.addActionListener(formListener);
 
161
        gridBagConstraints = new java.awt.GridBagConstraints();
 
162
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
 
163
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
 
164
        buttonsPanel.add(helpButton, gridBagConstraints);
 
165
 
 
166
        gridBagConstraints = new java.awt.GridBagConstraints();
 
167
        gridBagConstraints.gridy = 1;
 
168
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
 
169
        gridBagConstraints.weightx = 1.0;
 
170
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 11, 11);
 
171
        add(buttonsPanel, gridBagConstraints);
 
172
    }
 
173
 
 
174
    // Code for dispatching events from components to event handlers.
 
175
 
 
176
    private class FormListener implements java.awt.event.ActionListener {
 
177
        FormListener() {}
 
178
        public void actionPerformed(java.awt.event.ActionEvent evt) {
 
179
            if (evt.getSource() == okButton) {
 
180
                MergeDialogComponent.this.okButtonActionPerformed(evt);
 
181
            }
 
182
            else if (evt.getSource() == cancelButton) {
 
183
                MergeDialogComponent.this.cancelButtonActionPerformed(evt);
 
184
            }
 
185
            else if (evt.getSource() == helpButton) {
 
186
                MergeDialogComponent.this.helpButtonActionPerformed(evt);
 
187
            }
 
188
        }
 
189
    }// </editor-fold>//GEN-END:initComponents
 
190
    
 
191
    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
 
192
        // Add your handling code here:
 
193
        //List panelsToCloseList;
 
194
        Component[] panels;
 
195
        synchronized (this) {
 
196
            panels = mergeTabbedPane.getComponents();
 
197
        }
 
198
        boolean warning = false;
 
199
        ArrayList<String> unsavedPanelNames = new ArrayList<String>();
 
200
        ArrayList<SaveCookie> saveCookies = new ArrayList<SaveCookie>();
 
201
        for (int i = 0; i < panels.length; i++) {
 
202
            MergePanel panel = (MergePanel) panels[i];
 
203
            if((panel.getNumUnresolvedConflicts() > 0) && (!warning))
 
204
                warning = true;
 
205
            MergeNode node = nodesForPanels.get(panel);
 
206
            SaveCookie sc;
 
207
            if ((sc = node.getCookie(SaveCookie.class)) != null) {
 
208
                unsavedPanelNames.add(panel.getName());
 
209
                saveCookies.add(sc);
 
210
            }
 
211
        }
 
212
        Object ret;
 
213
        // XXX can format with one format string
 
214
        if (unsavedPanelNames.size() == 1) {           
 
215
            ret = DialogDisplayer.getDefault().notify(
 
216
            new NotifyDescriptor.Confirmation((warning)?NbBundle.getMessage(MergeDialogComponent.class,"SaveFileWarningQuestion",unsavedPanelNames.get(0)):
 
217
                                              NbBundle.getMessage(MergeDialogComponent.class,"SaveFileQuestion",unsavedPanelNames.get(0)),
 
218
                                              NotifyDescriptor.YES_NO_CANCEL_OPTION));
 
219
        } else if (unsavedPanelNames.size() > 1) {
 
220
            ret = DialogDisplayer.getDefault().notify(
 
221
                new NotifyDescriptor.Confirmation((warning)?NbBundle.getMessage(MergeDialogComponent.class,"SaveFilesWarningQuestion",new Integer(unsavedPanelNames.size())):
 
222
                                                  NbBundle.getMessage(MergeDialogComponent.class,"SaveFilesQuestion",new Integer(unsavedPanelNames.size())),
 
223
                                                  NotifyDescriptor.YES_NO_CANCEL_OPTION));
 
224
        } else {
 
225
            if(warning){
 
226
                ret = DialogDisplayer.getDefault().notify(
 
227
                new NotifyDescriptor.Confirmation(NbBundle.getMessage(MergeDialogComponent.class,"WarningQuestion",new Integer(unsavedPanelNames.size())),
 
228
                                                  NotifyDescriptor.OK_CANCEL_OPTION));
 
229
                if(ret.equals(NotifyDescriptor.NO_OPTION))
 
230
                    return;
 
231
            }else
 
232
                ret = NotifyDescriptor.YES_OPTION;
 
233
        }
 
234
        if (!NotifyDescriptor.YES_OPTION.equals(ret) && !NotifyDescriptor.NO_OPTION.equals(ret)) return ;
 
235
        if (NotifyDescriptor.YES_OPTION.equals(ret) || NotifyDescriptor.OK_OPTION.equals(ret)) {
 
236
            for (SaveCookie sc: saveCookies) {
 
237
                IOException ioException = null;
 
238
                try {
 
239
                    sc.save();
 
240
                } catch (UserQuestionException uqex) {
 
241
                    Object status = DialogDisplayer.getDefault().notify(
 
242
                        new NotifyDescriptor.Confirmation(uqex.getLocalizedMessage()));
 
243
                    if (status == NotifyDescriptor.OK_OPTION || status == NotifyDescriptor.YES_OPTION) {
 
244
                        boolean success;
 
245
                        try {
 
246
                            uqex.confirmed();
 
247
                            success = true;
 
248
                        } catch (IOException ioex) {
 
249
                            success = false;
 
250
                            ioException = ioex;
 
251
                        }
 
252
                        if (success) {
 
253
                            try {
 
254
                                sc.save();
 
255
                            } catch (IOException ioex) {
 
256
                                ioException = ioex;
 
257
                            }
 
258
                        }
 
259
                    } else if (status != NotifyDescriptor.NO_OPTION) {
 
260
                        // cancel
 
261
                        return ;
 
262
                    }
 
263
                } catch (IOException ioEx) {
 
264
                    ioException = ioEx;
 
265
                }
 
266
                if (ioException != null) {
 
267
                    ErrorManager.getDefault().notify(ioException);
 
268
                    // cancel the close - there was an error on save
 
269
                    return ;
 
270
                }
 
271
            }
 
272
        }
 
273
        for (int i = 0; i < panels.length; i++) {
 
274
            MergePanel panel = (MergePanel) panels[i];
 
275
            try {
 
276
                fireVetoableChange(PROP_PANEL_CLOSING, null, panel);
 
277
            } catch (PropertyVetoException pvex) {
 
278
                return ;
 
279
            }
 
280
            removeMergePanel(panel);
 
281
        }
 
282
    }//GEN-LAST:event_okButtonActionPerformed
 
283
    
 
284
    private void helpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_helpButtonActionPerformed
 
285
        Help help = (Help) Lookup.getDefault().lookup(Help.class);
 
286
        help.showHelp(getHelpCtx());
 
287
    }//GEN-LAST:event_helpButtonActionPerformed
 
288
    
 
289
    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
 
290
        // Add your handling code here:
 
291
        synchronized (this) {
 
292
            try {
 
293
                fireVetoableChange(PROP_ALL_CANCELLED, null, null);
 
294
            } catch (PropertyVetoException pvex) {}
 
295
            close();
 
296
        }
 
297
    }//GEN-LAST:event_cancelButtonActionPerformed
 
298
    
 
299
    protected void componentClosed() {
 
300
        Component[] panels;
 
301
        synchronized (this) {
 
302
            try {
 
303
                fireVetoableChange(PROP_ALL_CANCELLED, null, null);
 
304
            } catch (PropertyVetoException pvex) {}
 
305
 
 
306
            panels = mergeTabbedPane.getComponents();
 
307
        }
 
308
        for (int i = 0; i < panels.length; i++) {
 
309
            MergePanel panel = (MergePanel) panels[i];
 
310
            removeMergePanel(panel);
 
311
        }
 
312
    }
 
313
    
 
314
    /** @return Preferred size of editor top component  */
 
315
    public Dimension getPreferredSize() {
 
316
        Rectangle bounds = WindowManager.getDefault().getCurrentWorkspace().getBounds();
 
317
        return new Dimension(bounds.width / 2, (int) (bounds.height / 1.25));
 
318
    }
 
319
 
 
320
    public int getPersistenceType() {
 
321
        return TopComponent.PERSISTENCE_NEVER;
 
322
    }
 
323
 
 
324
    // Variables declaration - do not modify//GEN-BEGIN:variables
 
325
    private javax.swing.JPanel buttonsPanel;
 
326
    private javax.swing.JButton cancelButton;
 
327
    private javax.swing.JButton helpButton;
 
328
    private javax.swing.JTabbedPane mergeTabbedPane;
 
329
    private javax.swing.JButton okButton;
 
330
    // End of variables declaration//GEN-END:variables
 
331
    
 
332
    public void addNotify() {
 
333
        super.addNotify();
 
334
                javax.swing.JRootPane root = getRootPane();
 
335
                if (root != null) root.setDefaultButton(okButton);
 
336
                /*
 
337
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
 
338
            public void run() {
 
339
                javax.swing.JRootPane root = getRootPane();
 
340
                if (root != null) root.setDefaultButton(okButton);
 
341
            }
 
342
        });
 
343
                 */
 
344
    }
 
345
    
 
346
    private void initListeners() {
 
347
        mergeTabbedPane.addMouseListener(new PopupMenuImpl());
 
348
        mergeTabbedPane.addChangeListener(this);
 
349
    }
 
350
 
 
351
    public void open(Workspace workspace) {
 
352
        super.open(workspace);
 
353
        requestActive();
 
354
    }
 
355
    
 
356
    public synchronized void addMergePanel(MergePanel panel) {
 
357
        mergeTabbedPane.addTab(panel.getName(), panel);
 
358
        MergeNode node = new MergeNode(panel);
 
359
        nodesForPanels.put(panel, node);
 
360
        mergeTabbedPane.setSelectedComponent(panel);
 
361
        setActivatedNodes(new Node[] { node });
 
362
    }
 
363
    
 
364
    public synchronized void removeMergePanel(MergePanel panel) {
 
365
        mergeTabbedPane.remove(panel);
 
366
        nodesForPanels.remove(panel);
 
367
        if (mergeTabbedPane.getTabCount() == 0) {
 
368
            try {
 
369
                fireVetoableChange(PROP_ALL_CLOSED, null, null);
 
370
            } catch (PropertyVetoException pvex) {
 
371
                return ;
 
372
            }
 
373
            close();
 
374
        }
 
375
    }
 
376
    
 
377
    public MergePanel getSelectedMergePanel() {
 
378
        Component selected = mergeTabbedPane.getSelectedComponent();
 
379
        if (selected == null || !(selected instanceof MergePanel)) return null;
 
380
        return ((MergePanel) selected);
 
381
    }
 
382
    
 
383
    private static JPopupMenu createPopupMenu(MergePanel panel) {
 
384
        JPopupMenu popup = new JPopupMenuPlus();
 
385
        SystemAction[] actions = panel.getSystemActions();
 
386
        for (int i = 0; i < actions.length; i++) {
 
387
            if (actions[i] == null) {
 
388
                popup.addSeparator();
 
389
            } else if (actions[i] instanceof CallableSystemAction) {
 
390
                popup.add(((CallableSystemAction)actions[i]).getPopupPresenter());
 
391
                //add FileSystemAction to pop-up menu
 
392
            } else if (actions[i] instanceof FileSystemAction) {
 
393
                popup.add(((FileSystemAction)actions[i]).getPopupPresenter());
 
394
            }
 
395
        }
 
396
        return popup;
 
397
    }
 
398
    
 
399
    /** Shows given popup on given coordinations and takes care about the
 
400
     *  situation when menu can exceed screen limits.
 
401
     *  Copied from org.netbeans.core.windows.frames.DefaultContainerImpl
 
402
     */
 
403
    private static void showPopupMenu(JPopupMenu popup, Point p, Component comp) {
 
404
        SwingUtilities.convertPointToScreen(p, comp);
 
405
        Dimension popupSize = popup.getPreferredSize();
 
406
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
 
407
        
 
408
        if (p.x + popupSize.width > screenSize.width) {
 
409
            p.x = screenSize.width - popupSize.width;
 
410
        }
 
411
        if (p.y + popupSize.height > screenSize.height) {
 
412
            p.y = screenSize.height - popupSize.height;
 
413
        }
 
414
        SwingUtilities.convertPointFromScreen(p, comp);
 
415
        popup.show(comp, p.x, p.y);
 
416
    }
 
417
    
 
418
    /** Listen on tabbed pane merge panel selection */
 
419
    public void stateChanged(javax.swing.event.ChangeEvent changeEvent) {
 
420
        MergePanel panel = (MergePanel) mergeTabbedPane.getSelectedComponent();
 
421
        if (panel != null) {
 
422
            Node node = nodesForPanels.get(panel);
 
423
            if (node != null) {
 
424
                setActivatedNodes(new Node[] { node });
 
425
            }
 
426
        }
 
427
    }
 
428
    
 
429
    /** Popup menu reaction implementation */
 
430
    private class PopupMenuImpl extends MouseUtils.PopupMouseAdapter {
 
431
        public PopupMenuImpl () {}
 
432
        
 
433
        /** Called when the seqeunce of mouse events should lead to actual
 
434
         *  showing of the popup menu. */
 
435
        protected void showPopup(java.awt.event.MouseEvent mouseEvent) {
 
436
            TabbedPaneUI tabUI = mergeTabbedPane.getUI();
 
437
            int clickTab = tabUI.tabForCoordinate(mergeTabbedPane, mouseEvent.getX(), mouseEvent.getY());
 
438
            MergePanel panel = getSelectedMergePanel();
 
439
            if (panel == null) {
 
440
                return;
 
441
            }
 
442
            if (clickTab != -1) {
 
443
                //Click is on valid tab, not on empty area in tab
 
444
                showPopupMenu(createPopupMenu(panel), mouseEvent.getPoint(), mergeTabbedPane);
 
445
            }
 
446
        }
 
447
        
 
448
    }
 
449
    
 
450
    private class MergeNode extends org.openide.nodes.AbstractNode implements PropertyChangeListener, SaveCookie {
 
451
        
 
452
        private Reference<MergePanel> mergePanelRef;
 
453
        
 
454
        public MergeNode(MergePanel panel) {
 
455
            super(org.openide.nodes.Children.LEAF);
 
456
            panel.addPropertyChangeListener(WeakListeners.propertyChange(this, panel));
 
457
            mergePanelRef = new WeakReference<MergePanel>(panel);
 
458
            getCookieSet().add(new CloseCookieImpl());
 
459
            //activateSave();
 
460
        }
 
461
        
 
462
        private void activateSave() {
 
463
            getCookieSet().add(this);
 
464
        }
 
465
        
 
466
        private void deactivateSave() {
 
467
            getCookieSet().remove(this);
 
468
        }
 
469
        
 
470
        public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
 
471
            if (MergePanel.PROP_CAN_BE_SAVED.equals(propertyChangeEvent.getPropertyName())) {
 
472
                activateSave();
 
473
            } else if (MergePanel.PROP_CAN_NOT_BE_SAVED.equals(propertyChangeEvent.getPropertyName())) {
 
474
                deactivateSave();
 
475
            }
 
476
        }
 
477
        
 
478
        public void save() throws java.io.IOException {
 
479
            try {
 
480
                MergeDialogComponent.this.fireVetoableChange(PROP_PANEL_SAVE, null, mergePanelRef.get());
 
481
            } catch (PropertyVetoException vetoEx) {
 
482
                Throwable cause = vetoEx.getCause();
 
483
                if (cause instanceof IOException) {
 
484
                    throw (IOException) cause;
 
485
                } else {
 
486
                    throw new java.io.IOException(vetoEx.getLocalizedMessage());
 
487
                }
 
488
            }
 
489
            //System.out.println("SAVE called.");
 
490
            //deactivateSave();
 
491
        }
 
492
        
 
493
        private class CloseCookieImpl extends Object implements CloseCookie {
 
494
            public CloseCookieImpl () {}
 
495
        
 
496
            public boolean close() {
 
497
                try {
 
498
                    MergeDialogComponent.this.fireVetoableChange(PROP_PANEL_CLOSING, null, mergePanelRef.get());
 
499
                } catch (PropertyVetoException vetoEx) {
 
500
                    return false;
 
501
                }
 
502
                removeMergePanel(mergePanelRef.get());
 
503
                return true;
 
504
            }
 
505
        }
 
506
        
 
507
    }
 
508
}