KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > multiview > XmlMultiViewEditorSupport


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.multiview;
21
22 import java.io.ByteArrayOutputStream JavaDoc;
23 import java.io.UnsupportedEncodingException JavaDoc;
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.nio.charset.Charset JavaDoc;
26 import java.nio.charset.CharsetEncoder JavaDoc;
27 import javax.swing.SwingUtilities JavaDoc;
28 import org.netbeans.core.api.multiview.MultiViewHandler;
29 import org.netbeans.core.api.multiview.MultiViews;
30 import org.netbeans.core.spi.multiview.CloseOperationHandler;
31 import org.netbeans.core.spi.multiview.CloseOperationState;
32 import org.netbeans.core.spi.multiview.MultiViewDescription;
33 import org.netbeans.core.spi.multiview.MultiViewElement;
34 import org.netbeans.core.spi.multiview.MultiViewFactory;
35 import org.netbeans.modules.xml.api.EncodingUtil;
36 import org.netbeans.modules.xml.multiview.ui.ToolBarDesignEditor;
37 import org.openide.DialogDisplayer;
38 import org.openide.NotifyDescriptor;
39 import org.openide.ErrorManager;
40 import org.openide.filesystems.FileUtil;
41 import org.openide.text.NbDocument;
42 import org.openide.util.Task;
43 import org.openide.util.RequestProcessor;
44 import org.openide.util.NbBundle;
45 import org.openide.cookies.EditCookie;
46 import org.openide.cookies.EditorCookie;
47 import org.openide.cookies.OpenCookie;
48 import org.openide.cookies.PrintCookie;
49 import org.openide.filesystems.FileLock;
50 import org.openide.filesystems.FileObject;
51 import org.openide.text.DataEditorSupport;
52 import org.openide.text.CloneableEditor;
53 import org.openide.windows.CloneableOpenSupport;
54 import org.openide.windows.CloneableTopComponent;
55 import org.openide.windows.Mode;
56 import org.openide.windows.TopComponent;
57 import org.openide.windows.WindowManager;
58
59 import javax.swing.text.StyledDocument JavaDoc;
60 import javax.swing.text.Document JavaDoc;
61 import javax.swing.text.BadLocationException JavaDoc;
62 import javax.swing.text.EditorKit JavaDoc;
63 import javax.swing.event.DocumentListener JavaDoc;
64 import java.io.IOException JavaDoc;
65 import java.io.Serializable JavaDoc;
66 import java.io.OutputStream JavaDoc;
67 import java.io.InputStream JavaDoc;
68 import java.io.InputStreamReader JavaDoc;
69 import java.io.OutputStreamWriter JavaDoc;
70 import java.beans.PropertyChangeListener JavaDoc;
71 import java.beans.PropertyChangeEvent JavaDoc;
72 import java.util.Set JavaDoc;
73 import java.util.Iterator JavaDoc;
74 import java.util.Enumeration JavaDoc;
75 import java.lang.*;
76
77 /**
78  * An implementation of <code>DataEditorSupport</code> that is
79  * <code>XmlMultiViewDataObject</code> specific.
80  *
81  * Created on October 5, 2004, 10:46 AM
82  * @author mkuchtiak
83  */

84 public class XmlMultiViewEditorSupport extends DataEditorSupport implements Serializable JavaDoc, EditCookie, OpenCookie,
85         EditorCookie.Observable, PrintCookie {
86     
87     private XmlMultiViewDataObject dObj;
88     private DocumentListener JavaDoc docListener;
89     private int xmlMultiViewIndex;
90     private TopComponent mvtc;
91     private int lastOpenView = 0;
92     private TopComponentsListener topComponentsListener;
93     private MultiViewDescription[] multiViewDescriptions;
94     private XmlMultiViewEditorSupport.DocumentSynchronizer documentSynchronizer;
95     private int loading = 0;
96     private FileLock saveLock;
97     private static final String JavaDoc PROPERTY_MODIFICATION_LISTENER = "modificationListener"; // NOI18N;
98
/**
99      * Indicates whether xml view should be shown or not.
100      */

101     private boolean suppressXmlView = false;
102     
103     public XmlMultiViewEditorSupport() {
104         super(null, null);
105     }
106     
107     /** Creates a new instance of XmlMultiviewEditorSupport */
108     public XmlMultiViewEditorSupport(XmlMultiViewDataObject dObj) {
109         super(dObj, new XmlEnv(dObj));
110         this.dObj = dObj;
111         documentSynchronizer = new DocumentSynchronizer(dObj);
112         
113         // Set a MIME type as needed, e.g.:
114
setMIMEType("text/xml"); // NOI18N
115

116         docListener = new DocumentListener JavaDoc() {
117             public void changedUpdate(javax.swing.event.DocumentEvent JavaDoc e) {
118                 doUpdate();
119             }
120             
121             public void insertUpdate(javax.swing.event.DocumentEvent JavaDoc e) {
122                 doUpdate();
123             }
124             
125             public void removeUpdate(javax.swing.event.DocumentEvent JavaDoc e) {
126                 doUpdate();
127             }
128             
129             private void doUpdate() {
130                 if (saveLock == null) {
131                     documentSynchronizer.requestUpdateData();
132                 }
133             }
134         };
135         
136         // the document listener is added when the document is loaded
137
addPropertyChangeListener(new java.beans.PropertyChangeListener JavaDoc() {
138             public void propertyChange(java.beans.PropertyChangeEvent JavaDoc evt) {
139                 if (EditorCookie.Observable.PROP_DOCUMENT.equals(evt.getPropertyName())) {
140                     Document document = getDocument();
141                     if (document != null) {
142                         document.addDocumentListener(docListener);
143                     }
144                 }
145             }
146         });
147         
148         
149     }
150     
151     /** providing an UndoRedo object for XMLMultiViewElement
152      */

153     org.openide.awt.UndoRedo getUndoRedo0() {
154         return super.getUndoRedo();
155     }
156     
157     public XmlEnv getXmlEnv() {
158         return (XmlEnv) env;
159     }
160     
161     /** method enabled to create Cloneable Editor
162      */

163     protected CloneableEditor createCloneableEditor() {
164         return super.createCloneableEditor();
165     }
166     
167     public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
168         return super.getInputStream();
169     }
170     
171     protected Task reloadDocument() {
172         loading++;
173         documentSynchronizer.reloadingStarted();
174         FileLock reloadLock;
175         try {
176             reloadLock = dObj.waitForLock();
177             dObj.getDataCache().loadData(dObj.getPrimaryFile(), reloadLock);
178         } catch (IOException JavaDoc e) {
179             reloadLock = null;
180             ErrorManager.getDefault().notify(e);
181         }
182         final Task reloadDocumentTask = XmlMultiViewEditorSupport.super.reloadDocument();
183         final FileLock lock = reloadLock;
184         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
185             public void run() {
186                 try {
187                     if (!reloadDocumentTask.isFinished()) {
188                         reloadDocumentTask.waitFinished(5000);
189                     }
190                 } catch (InterruptedException JavaDoc e) {
191                     ErrorManager.getDefault().annotate(e, NbBundle.getMessage(XmlMultiViewEditorSupport.class,
192                             "CANNOT_UPDATE_LOCKED_DATA_OBJECT"));
193                 } finally {
194                     if (lock != null) {
195                         lock.releaseLock();
196                     }
197                     documentSynchronizer.reloadingFinished();
198                     loading--;
199                 }
200             }
201         });
202         return reloadDocumentTask;
203     }
204     
205     protected void loadFromStreamToKit(StyledDocument JavaDoc doc, InputStream JavaDoc stream, EditorKit JavaDoc kit)
206     throws IOException JavaDoc, BadLocationException JavaDoc {
207         kit.read(new InputStreamReader JavaDoc(stream, dObj.getEncodingHelper().getEncoding()), doc, 0);
208     }
209     
210     protected void saveFromKitToStream(StyledDocument JavaDoc doc, EditorKit JavaDoc kit, OutputStream JavaDoc stream)
211     throws IOException JavaDoc, BadLocationException JavaDoc {
212         kit.write(new OutputStreamWriter JavaDoc(stream, dObj.getEncodingHelper().getEncoding()), doc, 0, doc.getLength());
213     }
214     
215     public StyledDocument JavaDoc openDocument() throws IOException JavaDoc {
216         dObj.getDataCache().getStringData();
217         return super.openDocument();
218     }
219     
220     public void saveDocument() throws IOException JavaDoc {
221         if (loading > 0) {
222             return;
223         }
224         FileLock dataLock = ((XmlMultiViewDataObject) getDataObject()).waitForLock();
225         try {
226             ((XmlMultiViewDataObject) getDataObject()).getDataCache().saveData(dataLock);
227         } finally {
228             dataLock.releaseLock();
229         }
230     }
231     
232     void saveDocument(FileLock dataLock) throws IOException JavaDoc {
233         if (saveLock != dataLock) {
234             saveLock = dataLock;
235             documentSynchronizer.reloadModel();
236             try {
237                 doSaveDocument();
238                 dObj.getDataCache().resetFileTime();
239             } finally {
240                 saveLock = null;
241             }
242         }
243     }
244     
245     private void doSaveDocument() throws IOException JavaDoc {
246         // code below is basically a copy-paste from XmlJ2eeEditorSupport
247

248         final StyledDocument JavaDoc doc = getDocument();
249         // dependency on xml/core
250
String JavaDoc enc = EncodingUtil.detectEncoding(doc);
251         if (enc == null) enc = "UTF8"; //!!! // NOI18N
252

253         try {
254             //test encoding on dummy stream
255
new OutputStreamWriter JavaDoc(new ByteArrayOutputStream JavaDoc(1), enc);
256             if (!checkCharsetConversion(enc)) {
257                 return;
258             }
259             super.saveDocument();
260             //moved from Env.save()
261
getDataObject().setModified(false);
262         } catch (UnsupportedEncodingException JavaDoc ex) {
263             // ask user what next?
264
String JavaDoc message = NbBundle.getMessage(XmlMultiViewEditorSupport.class,"TEXT_SAVE_AS_UTF", enc);
265             NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(message);
266             Object JavaDoc res = DialogDisplayer.getDefault().notify(descriptor);
267             
268             if (res.equals(NotifyDescriptor.YES_OPTION)) {
269                 
270                 // update prolog to new valid encoding
271

272                 try {
273                     final int MAX_PROLOG = 1000;
274                     int maxPrologLen = Math.min(MAX_PROLOG, doc.getLength());
275                     final char prolog[] = doc.getText(0, maxPrologLen).toCharArray();
276                     int prologLen = 0; // actual prolog length
277

278                     //parse prolog and get prolog end
279
if (prolog[0] == '<' && prolog[1] == '?' && prolog[2] == 'x') {
280                         
281                         // look for delimitting ?>
282
for (int i = 3; i<maxPrologLen; i++) {
283                             if (prolog[i] == '?' && prolog[i+1] == '>') {
284                                 prologLen = i + 1;
285                                 break;
286                             }
287                         }
288                     }
289                     
290                     final int passPrologLen = prologLen;
291                     
292                     Runnable JavaDoc edit = new Runnable JavaDoc() {
293                         public void run() {
294                             try {
295                                 
296                                 doc.remove(0, passPrologLen + 1); // +1 it removes exclusive
297
doc.insertString(0, "<?xml version='1.0' encoding='UTF-8' ?> \n<!-- was: " + new String JavaDoc(prolog, 0, passPrologLen + 1) + " -->", null); // NOI18N
298

299                             } catch (BadLocationException JavaDoc e) {
300                                 if (System.getProperty("netbeans.debug.exceptions") != null) // NOI18N
301
e.printStackTrace();
302                             }
303                         }
304                     };
305                     
306                     NbDocument.runAtomic(doc, edit);
307                     
308                     super.saveDocument();
309                     //moved from Env.save()
310
getDataObject().setModified(false);
311                     // need to force reloading
312
((XmlMultiViewDataObject) getDataObject()).getDataCache().reloadData();
313                     
314                     
315                 } catch (BadLocationException JavaDoc lex) {
316                     ErrorManager.getDefault().notify(lex);
317                 }
318                 
319             } else { // NotifyDescriptor != YES_OPTION
320
return;
321             }
322         }
323     }
324     
325     private boolean checkCharsetConversion(final String JavaDoc encoding) {
326         boolean value = true;
327         try {
328             CharsetEncoder JavaDoc coder = Charset.forName(encoding).newEncoder();
329             if (!coder.canEncode(getDocument().getText(0, getDocument().getLength()))){
330                 NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
331                         NbBundle.getMessage(XmlMultiViewEditorSupport.class, "MSG_BadCharConversion",
332                         new Object JavaDoc [] { getDataObject().getPrimaryFile().getNameExt(),
333                         encoding}),
334                         NotifyDescriptor.YES_NO_OPTION,
335                         NotifyDescriptor.WARNING_MESSAGE);
336                 nd.setValue(NotifyDescriptor.NO_OPTION);
337                 DialogDisplayer.getDefault().notify(nd);
338                 if(nd.getValue() != NotifyDescriptor.YES_OPTION) {
339                     value = false;
340                 }
341             }
342         } catch (BadLocationException JavaDoc e){
343             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
344         }
345         return value;
346     }
347     
348     protected CloneableTopComponent createCloneableTopComponent() {
349         MultiViewDescription[] descs = getMultiViewDescriptions();
350         
351         CloneableTopComponent mvtc =
352                 MultiViewFactory.createCloneableMultiView(descs, descs[0], new MyCloseHandler(dObj));
353         
354         // #45665 - dock into editor mode if possible..
355
Mode editorMode = WindowManager.getDefault().findMode(org.openide.text.CloneableEditorSupport.EDITOR_MODE);
356         
357         if (editorMode != null) {
358             editorMode.dockInto(mvtc);
359         }
360         this.mvtc = mvtc;
361         return mvtc;
362     }
363     
364     public MultiViewDescription[] getMultiViewDescriptions() {
365         if (multiViewDescriptions == null) {
366             if (suppressXmlView) {
367                 multiViewDescriptions = dObj.getMultiViewDesc();
368                 xmlMultiViewIndex = 0;
369             } else {
370                 MultiViewDescription[] customDesc = dObj.getMultiViewDesc();
371                 MultiViewDescription xmlDesc = new XmlViewDesc(dObj);
372                 
373                 multiViewDescriptions = new MultiViewDescription[customDesc.length + 1];
374                 System.arraycopy(customDesc, 0, multiViewDescriptions, 0, customDesc.length);
375                 multiViewDescriptions[customDesc.length] = xmlDesc;
376                 xmlMultiViewIndex = customDesc.length;
377             }
378         }
379         return multiViewDescriptions;
380     }
381     
382     public void setSuppressXmlView(boolean suppressXmlView) {
383         this.suppressXmlView = suppressXmlView;
384         multiViewDescriptions = null;
385     }
386     
387     /** Focuses existing component to view, or if none exists creates new.
388      * The default implementation simply calls {@link #open}.
389      * @see org.openide.cookies.EditCookie#edit
390      */

391     public void edit() {
392         openView(-1);
393     }
394     
395     /**
396      * Opens the view identified by given <code>index</code>
397      * and calls <code>#openDocument()</code>.
398      * @param index the index of the view to be opened.
399      */

400     void openView(final int index) {
401         Utils.runInAwtDispatchThread(new Runnable JavaDoc() {
402             public void run() {
403                 CloneableTopComponent mvtc = openCloneableTopComponent();
404                 MultiViewHandler handler = MultiViews.findMultiViewHandler(mvtc);
405                 handler.requestVisible(handler.getPerspectives()[index < 0 ? xmlMultiViewIndex : index]);
406                 mvtc.requestActive();
407             }
408         });
409         try {
410             openDocument();
411         } catch (IOException JavaDoc ex) {
412             ErrorManager.getDefault().notify(ex);
413         }
414     }
415     
416     /** Overrides superclass method
417      */

418     public void open() {
419         openView(lastOpenView);
420     }
421     
422     void goToXmlPerspective() {
423         Utils.runInAwtDispatchThread(new Runnable JavaDoc() {
424             public void run() {
425                 MultiViewHandler handler = MultiViews.findMultiViewHandler(mvtc);
426                 handler.requestVisible(handler.getPerspectives()[xmlMultiViewIndex]);
427             }
428         });
429     }
430     /** Resolving problems when editor was modified and closed
431      * (issue 57483)
432      */

433     protected void notifyClosed() {
434         mvtc = null;
435         if (topComponentsListener != null) {
436             TopComponent.getRegistry().removePropertyChangeListener(topComponentsListener);
437             topComponentsListener = null;
438         }
439         Document document = getDocument();
440         if (document!=null) document.removeDocumentListener(docListener);
441         super.notifyClosed();
442     }
443     
444     org.netbeans.core.api.multiview.MultiViewPerspective getSelectedPerspective() {
445         if (mvtc != null) {
446             return MultiViews.findMultiViewHandler(mvtc).getSelectedPerspective();
447         }
448         return null;
449     }
450     
451     /**
452      * Updates the display name of the associated top component.
453      */

454     public void updateDisplayName() {
455         if (mvtc != null) {
456             Utils.runInAwtDispatchThread(new Runnable JavaDoc() {
457                 public void run() {
458                     String JavaDoc displayName = messageName();
459                     if (!displayName.equals(mvtc.getDisplayName())) {
460                         mvtc.setDisplayName(displayName);
461                     }
462                     mvtc.setToolTipText(FileUtil.getFileDisplayName(dObj.getPrimaryFile()));
463                 }
464             });
465         }
466     }
467     
468     
469     /** A description of the binding between the editor support and the object.
470      * Note this may be serialized as part of the window system and so
471      * should be static, and use the transient modifier where needed.
472      */

473     public static class XmlEnv extends DataEditorSupport.Env {
474         
475         private static final long serialVersionUID = 2882981960507292985L; //todo calculate a new one
476
private final XmlMultiViewDataObject xmlMultiViewDataObject;
477         
478         /** Create a new environment based on the buffer object.
479          * @param obj the buffer object to edit
480          */

481         public XmlEnv(XmlMultiViewDataObject obj) {
482             super(obj);
483             xmlMultiViewDataObject = obj;
484             changeFile();
485         }
486         
487         /** Get the file to edit.
488          * @return the primary file normally
489          */

490         protected FileObject getFile() {
491             return xmlMultiViewDataObject.getPrimaryFile();
492         }
493         
494         /** Lock the file to edit.
495          * Should be taken from the file entry if possible, helpful during
496          * e.g. deletion of the file.
497          * @return a lock on the primary file normally
498          * @throws IOException if the lock could not be taken
499          */

500         protected FileLock takeLock() throws IOException JavaDoc {
501             return xmlMultiViewDataObject.getPrimaryEntry().takeLock();
502         }
503         
504         
505         /** Find the editor support this environment represents.
506          * Note that we have to look it up, as keeping a direct
507          * reference would not permit this environment to be serialized.
508          * @return the editor support
509          */

510         public CloneableOpenSupport findCloneableOpenSupport() {
511             return xmlMultiViewDataObject.getEditorSupport();
512         }
513         
514         public InputStream JavaDoc inputStream() throws IOException JavaDoc {
515             return xmlMultiViewDataObject.getDataCache().createInputStream();
516         }
517         
518         protected OutputStream JavaDoc getFileOutputStream() throws IOException JavaDoc {
519             return super.outputStream();
520         }
521         
522         public OutputStream JavaDoc outputStream() throws IOException JavaDoc {
523             if (xmlMultiViewDataObject.getEditorSupport().saveLock != null) {
524                 return super.outputStream();
525             } else {
526                 return xmlMultiViewDataObject.getDataCache().createOutputStream();
527             }
528         }
529         
530         public boolean isModified() {
531             return super.isModified();
532         }
533     }
534     
535     private static class XmlViewDesc implements MultiViewDescription, java.io.Serializable JavaDoc {
536         
537         private static final long serialVersionUID = 8085725367398466167L;
538         XmlMultiViewDataObject dObj;
539         
540         XmlViewDesc() {
541         }
542         
543         XmlViewDesc(XmlMultiViewDataObject dObj) {
544             this.dObj = dObj;
545         }
546         
547         public MultiViewElement createElement() {
548             return new XmlMultiViewElement(dObj);
549         }
550         
551         public String JavaDoc getDisplayName() {
552             return org.openide.util.NbBundle.getMessage(XmlMultiViewEditorSupport.class, "LBL_XML_TAB");
553         }
554         
555         public org.openide.util.HelpCtx getHelpCtx() {
556             return dObj.getHelpCtx();
557         }
558         
559         public java.awt.Image JavaDoc getIcon() {
560             return dObj.getXmlViewIcon();
561         }
562         
563         public int getPersistenceType() {
564             return TopComponent.PERSISTENCE_ONLY_OPENED;
565         }
566         
567         public String JavaDoc preferredID() {
568             return "multiview_xml"; //NOI18N
569
}
570     }
571     
572     public TopComponent getMVTC() {
573         return mvtc;
574     }
575     
576     void setMVTC(TopComponent mvtc) {
577         this.mvtc = mvtc;
578         if (topComponentsListener == null) {
579             topComponentsListener = new TopComponentsListener();
580             TopComponent.getRegistry().addPropertyChangeListener(topComponentsListener);
581         }
582     }
583     
584     void setLastOpenView(int index) {
585         lastOpenView = index;
586     }
587     
588     private class DocumentSynchronizer extends XmlMultiViewDataSynchronizer {
589         
590         private final RequestProcessor.Task reloadUpdatedTask = requestProcessor.create(new Runnable JavaDoc() {
591             public void run() {
592                 Document document = getDocument();
593                 DocumentListener JavaDoc listener = document == null ? null :
594                     (DocumentListener JavaDoc) document.getProperty(PROPERTY_MODIFICATION_LISTENER);
595                 if (listener != null) {
596                     document.removeDocumentListener(listener);
597                 }
598                 try {
599                     reloadModel();
600                 } finally {
601                     if (listener != null) {
602                         document.addDocumentListener(listener);
603                     }
604                 }
605             }
606         });
607         
608         
609         public DocumentSynchronizer(XmlMultiViewDataObject dataObject) {
610             super(dataObject, 100);
611             getXmlEnv().addPropertyChangeListener(new PropertyChangeListener JavaDoc() {
612                 public void propertyChange(PropertyChangeEvent JavaDoc evt) {
613                     String JavaDoc propertyName = evt.getPropertyName();
614                     if (Env.PROP_TIME.equals(propertyName) && getDocument() == null) {
615                         dObj.getDataCache().loadData();
616                     }
617                 }
618             });
619         }
620         
621         protected boolean mayUpdateData(boolean allowDialog) {
622             return true;
623         }
624         
625         protected void dataUpdated(long timeStamp) {
626             if (loading == 0) {
627                 reloadUpdatedTask.schedule(0);
628             }
629         }
630         
631         protected Object JavaDoc getModel() {
632             return getDocument();
633         }
634         
635         protected void updateDataFromModel(Object JavaDoc model, final FileLock lock, final boolean modify) {
636             final Document doc = (Document) model;
637             if (doc == null) {
638                 try {
639                     dObj.getDataCache().setData(lock, "", modify); // NOI18N
640
} catch (IOException JavaDoc e) {
641                     ErrorManager.getDefault().notify(e);
642                 }
643             } else {
644                 // safely take the text from the document
645
doc.render(new Runnable JavaDoc() {
646                     public void run() {
647                         try {
648                             dObj.getDataCache().setData(lock, doc.getText(0, doc.getLength()), modify);
649                         } catch (BadLocationException JavaDoc e) {
650                             // impossible
651
} catch (IOException JavaDoc e) {
652                             ErrorManager.getDefault().notify(e);
653                         }
654                     }
655                 });
656             }
657         }
658         
659         protected void reloadModelFromData() {
660             if (loading == 0) {
661                 Utils.replaceDocument((StyledDocument JavaDoc)getDocument(), dObj.getDataCache().getStringData());
662             }
663         }
664     }
665     
666     static class MyCloseHandler implements CloseOperationHandler, java.io.Serializable JavaDoc {
667         static final long serialVersionUID = -6512103928294991474L;
668         private XmlMultiViewDataObject dObj;
669         MyCloseHandler() {
670         }
671         
672         MyCloseHandler(XmlMultiViewDataObject dObj) {
673             this.dObj = dObj;
674         }
675         
676         public boolean resolveCloseOperation(CloseOperationState[] elements) {
677             for (int i = 0; i < elements.length; i++) {
678                 CloseOperationState element = elements[i];
679                 if (ToolBarDesignEditor.PROPERTY_FLUSH_DATA.equals(element.getCloseWarningID())) {
680                     return false;
681                 }
682             }
683             if (dObj.isModified()) {
684                 XmlMultiViewEditorSupport support = dObj.getEditorSupport();
685                 String JavaDoc msg = support.messageSave();
686                 
687                 java.util.ResourceBundle JavaDoc bundle =
688                         org.openide.util.NbBundle.getBundle(org.openide.text.CloneableEditorSupport.class);
689                 
690                 javax.swing.JButton JavaDoc saveOption = new javax.swing.JButton JavaDoc(bundle.getString("CTL_Save")); // NOI18N
691
saveOption.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_CTL_Save")); // NOI18N
692
saveOption.getAccessibleContext().setAccessibleName(bundle.getString("ACSN_CTL_Save")); // NOI18N
693
javax.swing.JButton JavaDoc discardOption = new javax.swing.JButton JavaDoc(bundle.getString("CTL_Discard")); // NOI18N
694
discardOption.getAccessibleContext()
695                 .setAccessibleDescription(bundle.getString("ACSD_CTL_Discard")); // NOI18N
696
discardOption.getAccessibleContext().setAccessibleName(bundle.getString("ACSN_CTL_Discard")); // NOI18N
697
discardOption.setMnemonic(bundle.getString("CTL_Discard_Mnemonic").charAt(0)); // NOI18N
698

699                 NotifyDescriptor nd = new NotifyDescriptor(
700                         msg,
701                         bundle.getString("LBL_SaveFile_Title"),
702                         NotifyDescriptor.YES_NO_CANCEL_OPTION,
703                         NotifyDescriptor.QUESTION_MESSAGE,
704                         new Object JavaDoc[]{saveOption, discardOption, NotifyDescriptor.CANCEL_OPTION},
705                         saveOption
706                         );
707                 
708                 Object JavaDoc ret = org.openide.DialogDisplayer.getDefault().notify(nd);
709                 
710                 if (NotifyDescriptor.CANCEL_OPTION.equals(ret) || NotifyDescriptor.CLOSED_OPTION.equals(ret)) {
711                     return false;
712                 }
713                 
714                 if (saveOption.equals(ret)) {
715                     try {
716                         if (dObj.acceptEncoding()) {
717                             support.saveDocument();
718                         } else {
719                             return false;
720                         }
721                     } catch (java.io.IOException JavaDoc e) {
722                         org.openide.ErrorManager.getDefault().notify(e);
723                         return false;
724                     }
725                 } else if (discardOption.equals(ret)) {
726                     dObj.getEditorSupport().reloadDocument().waitFinished();
727                     support.notifyClosed();
728                 }
729             }
730             return true;
731         }
732     }
733     
734     // Accessibility for ToolBarMultiViewElement:
735
protected String JavaDoc messageName() {
736         return super.messageName();
737     }
738     
739     private class TopComponentsListener implements PropertyChangeListener JavaDoc {
740         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
741             if (TopComponent.Registry.PROP_OPENED.equals(evt.getPropertyName())) {
742                 // Check closed top components
743
Set JavaDoc closed = ((Set JavaDoc) evt.getOldValue());
744                 closed.removeAll((Set JavaDoc) evt.getNewValue());
745                 for (Iterator JavaDoc iterator = closed.iterator(); iterator.hasNext();) {
746                     Object JavaDoc o = iterator.next();
747                     if (o instanceof CloneableTopComponent) {
748                         final CloneableTopComponent topComponent = (CloneableTopComponent) o;
749                         Enumeration JavaDoc en = topComponent.getReference().getComponents();
750                         if (mvtc == topComponent) {
751                             if (en.hasMoreElements()) {
752                                 // Remember next cloned top component
753
mvtc = (CloneableTopComponent) en.nextElement();
754                             } else {
755                                 // All cloned top components are closed
756
notifyClosed();
757                             }
758                         }
759                     }
760                 }
761             }
762         }
763     }
764 }
765
Popular Tags