Revert: decouple image file editor from VirtualFile

(be7434a290)
This commit is contained in:
Shaverdova Elena
2011-12-15 17:07:08 +04:00
parent 18f6f35f2a
commit 30aee5b21e
8 changed files with 98 additions and 245 deletions
@@ -18,8 +18,8 @@ package org.intellij.images.editor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileListener;
import org.intellij.images.ui.ImageComponentDecorator;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -28,13 +28,9 @@ import javax.swing.*;
*
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface ImageEditor extends Disposable, ImageComponentDecorator {
@Nullable
public interface ImageEditor extends Disposable, VirtualFileListener, ImageComponentDecorator {
VirtualFile getFile();
long getFileLength();
Project getProject();
ImageDocument getDocument();
@@ -1,51 +0,0 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.intellij.images.editor.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import java.awt.image.BufferedImage;
import java.util.EventListener;
/**
* User: ksafonov
*/
public interface ImageContentProvider extends Disposable {
interface ImageContent {
@Nullable
BufferedImage getImage();
@Nullable
String getFormat();
}
interface ContentChangeListener extends EventListener {
void contentChanged();
}
ImageContent getContent();
void addContentChangeListener(ContentChangeListener listener);
@Nullable
VirtualFile getVirtualFile();
long getFileLength();
}
@@ -17,15 +17,16 @@ package org.intellij.images.editor.impl;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.*;
import org.intellij.images.editor.ImageDocument;
import org.intellij.images.editor.ImageEditor;
import org.intellij.images.editor.ImageZoomModel;
import org.intellij.images.fileTypes.ImageFileTypeManager;
import org.intellij.images.options.*;
import org.intellij.images.thumbnail.actionSystem.ThumbnailViewActions;
import org.intellij.images.ui.ImageComponent;
import org.intellij.images.vfs.IfsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -38,69 +39,58 @@ import java.beans.PropertyChangeListener;
*
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
final class ImageEditorImpl implements ImageEditor {
private final PropertyChangeListener optionsChangeListener = new OptionsChangeListener();
private final Project project;
private final ImageContentProvider contentProvider;
private final ImageEditorUI editorUI;
private boolean disposed;
final class ImageEditorImpl extends VirtualFileAdapter implements ImageEditor {
private final PropertyChangeListener optionsChangeListener = new OptionsChangeListener();
private final Project project;
private final VirtualFile file;
private final ImageEditorUI editorUI;
private boolean disposed;
ImageEditorImpl(@NotNull Project project, @NotNull final ImageContentProvider contentProvider) {
this.project = project;
this.contentProvider = contentProvider;
ImageEditorImpl(@NotNull Project project, @NotNull VirtualFile file) {
this.project = project;
this.file = file;
// Options
Options options = OptionsManager.getInstance().getOptions();
editorUI = new ImageEditorUI(this, options.getEditorOptions());
options.addPropertyChangeListener(optionsChangeListener);
contentProvider.addContentChangeListener(new ImageContentProvider.ContentChangeListener() {
public void contentChanged() {
setValue(contentProvider.getContent());
}
});
setValue(contentProvider.getContent());
}
private void setValue(ImageContentProvider.ImageContent content) {
ImageDocument document = editorUI.getImageComponent().getDocument();
BufferedImage image = content.getImage();
String format = content.getFormat();
if (image != null && format != null) {
BufferedImage previousImage = document.getValue();
document.setFormat(format);
document.setValue(image);
ImageZoomModel zoomModel = getZoomModel();
if (previousImage == null || !zoomModel.isZoomLevelChanged()) {
// Set smart zooming behaviour on open
// Options
Options options = OptionsManager.getInstance().getOptions();
ZoomOptions zoomOptions = options.getEditorOptions().getZoomOptions();
// Open as actual size
zoomModel.setZoomFactor(1.0d);
editorUI = new ImageEditorUI(this, options.getEditorOptions());
options.addPropertyChangeListener(optionsChangeListener);
if (zoomOptions.isSmartZooming()) {
Dimension prefferedSize = zoomOptions.getPrefferedSize();
if (prefferedSize.width > image.getWidth() && prefferedSize.height > image.getHeight()) {
// Resize to preferred size
// Calculate zoom factor
VirtualFileManager.getInstance().addVirtualFileListener(this);
setValue(file);
}
private void setValue(VirtualFile file) {
ImageDocument document = editorUI.getImageComponent().getDocument();
try {
BufferedImage previousImage = document.getValue();
BufferedImage image = IfsUtil.getImage(file);
document.setValue(image);
document.setFormat(IfsUtil.getFormat(file));
ImageZoomModel zoomModel = getZoomModel();
if (image != null && (previousImage == null || !zoomModel.isZoomLevelChanged())) {
// Set smart zooming behaviour on open
Options options = OptionsManager.getInstance().getOptions();
ZoomOptions zoomOptions = options.getEditorOptions().getZoomOptions();
// Open as actual size
zoomModel.setZoomFactor(1.0d);
if (zoomOptions.isSmartZooming()) {
Dimension prefferedSize = zoomOptions.getPrefferedSize();
if (prefferedSize.width > image.getWidth() && prefferedSize.height > image.getHeight()) {
// Resize to preffered size
// Calculate zoom factor
double factor = (prefferedSize.getWidth() / (double) image.getWidth() + prefferedSize.getHeight() / (double) image.getHeight()) / 2.0d;
zoomModel.setZoomFactor(Math.ceil(factor));
}
zoomModel.setZoomFactor(Math.ceil(factor));
}
}
}
} catch (Exception e) {
// Error loading image file
document.setValue(null);
}
}
}
else {
document.setValue(null);
document.setFormat(null);
// Close editor
VirtualFile file = contentProvider.getVirtualFile();
if (file != null) {
FileEditorManager editorManager = FileEditorManager.getInstance(project);
editorManager.closeFile(file);
}
}
}
public boolean isValid() {
ImageDocument document = editorUI.getImageComponent().getDocument();
@@ -115,14 +105,10 @@ final class ImageEditorImpl implements ImageEditor {
return editorUI.getImageComponent();
}
@Nullable
public VirtualFile getFile() {
return contentProvider.getVirtualFile();
}
public long getFileLength() {
return contentProvider.getFileLength();
}
@NotNull
public VirtualFile getFile() {
return file;
}
@NotNull
public Project getProject() {
@@ -168,9 +154,40 @@ final class ImageEditorImpl implements ImageEditor {
Options options = OptionsManager.getInstance().getOptions();
options.removePropertyChangeListener(optionsChangeListener);
editorUI.dispose();
VirtualFileManager.getInstance().removeVirtualFileListener(this);
disposed = true;
}
public void propertyChanged(VirtualFilePropertyEvent event) {
super.propertyChanged(event);
if (file.equals(event.getFile())) {
// Change document
file.refresh(true, false, new Runnable() {
public void run() {
if (ImageFileTypeManager.getInstance().isImage(file)) {
setValue(file);
} else {
setValue(null);
// Close editor
FileEditorManager editorManager = FileEditorManager.getInstance(project);
editorManager.closeFile(file);
}
}
});
}
}
public void contentsChanged(VirtualFileEvent event) {
super.contentsChanged(event);
if (file.equals(event.getFile())) {
// Change document
file.refresh(true, false, new Runnable() {
public void run() {
setValue(file);
}
});
}
}
private class OptionsChangeListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent evt) {
@@ -37,8 +37,8 @@ final class ImageEditorManagerImpl {
* @return Image editor for file
*/
@NotNull
public static ImageEditor createImageEditor(@NotNull Project project, @NotNull ImageContentProvider contentProvider) {
return new ImageEditorImpl(project, contentProvider);
public static ImageEditor createImageEditor(@NotNull Project project, @NotNull VirtualFile file) {
return new ImageEditorImpl(project, file);
}
/**
@@ -152,10 +152,11 @@ final class ImageEditorUI extends JPanel implements DataProvider {
} else {
format = format.toUpperCase();
}
VirtualFile file = editor.getFile();
infoLabel.setText(
ImagesBundle.message("image.info",
image.getWidth(), image.getHeight(), format,
colorModel.getPixelSize(), StringUtil.formatFileSize(editor.getFileLength())));
colorModel.getPixelSize(), file != null ? StringUtil.formatFileSize(file.getLength()) : ""));
} else {
infoLabel.setText(null);
}
@@ -347,8 +348,7 @@ final class ImageEditorUI extends JPanel implements DataProvider {
} else if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) {
return editor.getFile();
} else if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) {
final VirtualFile file = editor.getFile();
return file != null ? new VirtualFile[]{file} : null;
return new VirtualFile[]{editor.getFile()};
} else if (LangDataKeys.PSI_FILE.is(dataId)) {
return getData(LangDataKeys.PSI_ELEMENT.getName());
} else if (LangDataKeys.PSI_ELEMENT.is(dataId)) {
@@ -22,6 +22,8 @@ import com.intellij.openapi.fileEditor.FileEditorState;
import com.intellij.openapi.fileEditor.FileEditorStateLevel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import org.intellij.images.editor.ImageEditor;
import org.intellij.images.editor.ImageFileEditor;
import org.intellij.images.editor.ImageZoomModel;
@@ -43,8 +45,11 @@ final class ImageFileEditorImpl extends UserDataHolderBase implements ImageFileE
private static final String NAME = "ImageFileEditor";
private final ImageEditor imageEditor;
ImageFileEditorImpl(@NotNull Project project, @NotNull ImageContentProvider contentProvider) {
imageEditor = ImageEditorManagerImpl.createImageEditor(project, contentProvider);
ImageFileEditorImpl(@NotNull Project project, @NotNull VirtualFile file) {
imageEditor = ImageEditorManagerImpl.createImageEditor(project, file);
// Append file listener
VirtualFileManager.getInstance().addVirtualFileListener(imageEditor);
// Set background and grid default options
Options options = OptionsManager.getInstance().getOptions();
@@ -121,6 +126,7 @@ final class ImageFileEditorImpl extends UserDataHolderBase implements ImageFileE
}
public void dispose() {
VirtualFileManager.getInstance().removeVirtualFileListener(imageEditor);
ImageEditorManagerImpl.releaseImageEditor(imageEditor);
}
@@ -45,10 +45,7 @@ final class ImageFileEditorProvider implements FileEditorProvider, DumbAware {
@NotNull
public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
ImageContentProvider contentProvider = new VirtualFileImageContentProvider(file);
ImageFileEditorImpl editor = new ImageFileEditorImpl(project, contentProvider);
Disposer.register(editor, contentProvider);
return editor;
return new ImageFileEditorImpl(project, file);
}
public void disposeEditor(@NotNull FileEditor editor) {
@@ -1,112 +0,0 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.intellij.images.editor.impl;
import com.intellij.openapi.vfs.*;
import com.intellij.util.EventDispatcher;
import org.intellij.images.fileTypes.ImageFileTypeManager;
import org.intellij.images.vfs.IfsUtil;
import org.jetbrains.annotations.Nullable;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* User: ksafonov
*/
class VirtualFileImageContentProvider extends VirtualFileAdapter implements ImageContentProvider {
private final VirtualFile myFile;
private final EventDispatcher<ContentChangeListener> myEventDispatcher = EventDispatcher.create(ContentChangeListener.class);
private static final ImageContent NULL_CONTENT = new ImageContent() {
public BufferedImage getImage() {
return null;
}
public String getFormat() {
return null;
}
};
public VirtualFileImageContentProvider(final VirtualFile virtualFile) {
myFile = virtualFile;
VirtualFileManager.getInstance().addVirtualFileListener(this);
}
public ImageContent getContent() {
if (ImageFileTypeManager.getInstance().isImage(myFile)) {
return new ImageContent() {
@Nullable
public BufferedImage getImage() {
try {
return IfsUtil.getImage(myFile);
}
catch (IOException e) {
return null;
}
}
@Nullable
public String getFormat() {
try {
return IfsUtil.getFormat(myFile);
}
catch (IOException e) {
return null;
}
}
};
}
else {
return NULL_CONTENT;
}
}
public void addContentChangeListener(final ContentChangeListener listener) {
myEventDispatcher.addListener(listener, this);
}
public VirtualFile getVirtualFile() {
return myFile;
}
public long getFileLength() {
return myFile.getLength();
}
public void dispose() {
VirtualFileManager.getInstance().removeVirtualFileListener(this);
}
public void propertyChanged(VirtualFilePropertyEvent event) {
onFileChange(event);
}
public void contentsChanged(VirtualFileEvent event) {
onFileChange(event);
}
private void onFileChange(final VirtualFileEvent event) {
if (myFile.equals(event.getFile())) {
// Change document
myFile.refresh(true, false, new Runnable() {
public void run() {
myEventDispatcher.getMulticaster().contentChanged();
}
});
}
}
}