2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
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]"
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.
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.
43
package org.netbeans.modules.image;
46
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeListener;
48
import java.beans.PropertyVetoException;
49
import java.io.IOException;
50
import java.text.MessageFormat;
51
import java.util.Enumeration;
52
import javax.swing.Icon;
53
import javax.swing.SwingUtilities;
55
import org.openide.cookies.CloseCookie;
56
import org.openide.cookies.OpenCookie;
57
import org.openide.filesystems.FileChangeListener;
58
import org.openide.filesystems.FileChangeAdapter;
59
import org.openide.filesystems.FileEvent;
60
import org.openide.loaders.DataObject;
61
import org.openide.loaders.MultiDataObject;
62
import org.openide.loaders.OpenSupport;
63
import org.openide.NotifyDescriptor;
64
import org.openide.DialogDisplayer;
65
import org.openide.windows.CloneableOpenSupport;
66
import org.openide.windows.CloneableTopComponent;
67
import org.openide.util.NbBundle;
68
import org.openide.util.RequestProcessor;
69
import org.openide.util.RequestProcessor.Task;
73
* OpenSupport flavored with some <code>CloneableEditorSupport</code> features like
74
* listening on changes of image file and renames on dataobject,
75
* so it can work appropriate in Editor window.
77
* @author Peter Zavadsky
78
* @author Marian Petras
81
public class ImageOpenSupport extends OpenSupport implements OpenCookie, CloseCookie {
83
/** Saves last modified time. */
84
private long lastSaveTime;
86
/** Listens for changes on file. */
87
private FileChangeListener fileChangeL;
89
/** Reloading task. */
90
private Task reloadTask;
93
/** Constructs ImageOpenSupportObject on given MultiDataObject.Entry. */
94
public ImageOpenSupport(MultiDataObject.Entry entry) {
95
super(entry, new Environment(entry.getDataObject())); // TEMP
99
/** Creates the CloenableTOPComponent viewer of image. */
100
public CloneableTopComponent createCloneableTopComponent () {
102
return new ImageViewer((ImageDataObject)entry.getDataObject());
105
/** Set listener for changes on image file. */
106
void prepareViewer() {
107
// listen for changes on the image file
108
if(fileChangeL == null) {
109
fileChangeL = new FileChangeAdapter() {
110
public void fileChanged(final FileEvent evt) {
111
if(allEditors.isEmpty()) {
115
if(evt.getFile().isVirtual()) {
116
entry.getFile().removeFileChangeListener(this);
117
// File doesn't exist on disk - simulate env
119
((Environment)ImageOpenSupport.this.env).fileRemoved();
120
entry.getFile().addFileChangeListener(this);
124
if (evt.getTime() > lastSaveTime) {
125
lastSaveTime = System.currentTimeMillis();
128
if(reloadTask == null || reloadTask.isFinished()) {
130
reloadTask = RequestProcessor.postRequest(
142
entry.getFile().addFileChangeListener(fileChangeL);
143
lastSaveTime = System.currentTimeMillis();
146
/** Ask and reload/close image views. */
147
private void reload(FileEvent evt) {
149
// XXX the following is a resource path in NB 3.x and a URL after build system
150
// merge; better to produce something nicer (e.g. FileUtil.toFile):
151
String msg = NbBundle.getMessage(ImageOpenSupport.class, "MSG_ExternalChange", entry.getFile() );
152
NotifyDescriptor nd = new NotifyDescriptor.Confirmation(msg, NotifyDescriptor.YES_NO_OPTION);
153
Object ret = DialogDisplayer.getDefault().notify(nd);
155
if (NotifyDescriptor.YES_OPTION.equals(ret)) {
156
// due to compiler 1.2 bug only
157
final ImageDataObject imageObj = (ImageDataObject)entry.getDataObject();
158
final CloneableTopComponent.Ref editors = allEditors;
160
Enumeration e = editors.getComponents();
161
while(e.hasMoreElements()) {
162
final Object pane = e.nextElement();
163
SwingUtilities.invokeLater(new Runnable() {
165
((ImageViewer)pane).updateView(imageObj);
172
/** Environment for image open support. */
173
private static class Environment extends OpenSupport.Env {
174
/** generated Serialized Version UID */
175
static final long serialVersionUID = -1934890789745432254L;
178
public Environment(DataObject dataObject) {
183
/** Overrides superclass method. Gets from OpenCookie. */
184
public CloneableOpenSupport findCloneableOpenSupport() {
185
return (CloneableOpenSupport)getDataObject().getCookie(OpenCookie.class);
188
/** Called from enclosing support.
189
* The components are going to be closed anyway and in case of
190
* modified document its asked before if to save the change. */
191
private void fileRemoved() {
193
fireVetoableChange(PROP_VALID, Boolean.TRUE, Boolean.FALSE);
194
} catch(PropertyVetoException pve) {
198
firePropertyChange(PROP_VALID, Boolean.TRUE, Boolean.FALSE);
200
} // End of nested Environment class.