/*
* Copyright 2000-2009 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 com.intellij.openapi.fileEditor.impl.http;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.http.FileDownloadingListener;
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
import com.intellij.openapi.vfs.impl.http.RemoteFileInfo;
import com.intellij.openapi.vfs.impl.http.RemoteFileState;
import com.intellij.util.EventDispatcher;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* @author nik
*/
public class RemoteFilePanel implements PropertyChangeListener {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.http.RemoteFilePanel");
@NonNls private static final String ERROR_CARD = "error";
@NonNls private static final String DOWNLOADING_CARD = "downloading";
@NonNls private static final String EDITOR_CARD = "editor";
private JPanel myMainPanel;
private JLabel myProgressLabel;
private JProgressBar myProgressBar;
private JButton myCancelButton;
private JPanel myContentPanel;
private JLabel myErrorLabel;
private JButton myTryAgainButton;
private JButton myChangeProxySettingsButton;
private JPanel myEditorPanel;
private JTextField myUrlTextField;
private JPanel myToolbarPanel;
private final Project myProject;
private final HttpVirtualFile myVirtualFile;
private final MergingUpdateQueue myProgressUpdatesQueue;
private final MyDownloadingListener myDownloadingListener;
private final EventDispatcher<PropertyChangeListener> myDispatcher = EventDispatcher.create(PropertyChangeListener.class);
private @Nullable TextEditor myFileEditor;
public RemoteFilePanel(final Project project, final HttpVirtualFile virtualFile) {
myProject = project;
myVirtualFile = virtualFile;
myErrorLabel.setIcon(AllIcons.RunConfigurations.ConfigurationWarning);
myUrlTextField.setText(virtualFile.getUrl());
myProgressUpdatesQueue = new MergingUpdateQueue("downloading progress updates", 300, false, myMainPanel);
initToolbar(project);
final RemoteFileInfo remoteFileInfo = virtualFile.getFileInfo();
myDownloadingListener = new MyDownloadingListener();
remoteFileInfo.addDownloadingListener(myDownloadingListener);
myCancelButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
remoteFileInfo.cancelDownloading();
}
});
myTryAgainButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
showCard(DOWNLOADING_CARD);
remoteFileInfo.restartDownloading();
}
});
myChangeProxySettingsButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
HttpConfigurable.editConfigurable(myMainPanel);
}
});
showCard(DOWNLOADING_CARD);
remoteFileInfo.startDownloading();
if (remoteFileInfo.getState() == RemoteFileState.DOWNLOADED) {
switchEditor();
}
else {
String errorMessage = remoteFileInfo.getErrorMessage();
if (errorMessage != null) {
myDownloadingListener.errorOccurred(errorMessage);
}
}
}
private void initToolbar(Project project) {
DefaultActionGroup group = new DefaultActionGroup();
group.add(new RefreshRemoteFileAction(myVirtualFile));
for (RemoteFileEditorActionProvider actionProvider : RemoteFileEditorActionProvider.EP_NAME.getExtensions()) {
group.addAll(actionProvider.createToolbarActions(project, myVirtualFile));
}
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
myToolbarPanel.add(actionToolbar.getComponent(), BorderLayout.CENTER);
}
private void showCard(final String name) {
((CardLayout)myContentPanel.getLayout()).show(myContentPanel, name);
}
private void switchEditor() {
LOG.debug("Switching editor...");
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
final TextEditor textEditor = (TextEditor)TextEditorProvider.getInstance().createEditor(myProject, myVirtualFile);
textEditor.addPropertyChangeListener(RemoteFilePanel.this);
myEditorPanel.removeAll();
myEditorPanel.add(textEditor.getComponent(), BorderLayout.CENTER);
myFileEditor = textEditor;
showCard(EDITOR_CARD);
LOG.debug("Editor for downloaded file opened.");
}
});
}
@Nullable
public TextEditor getFileEditor() {
return myFileEditor;
}
public JPanel getMainPanel() {
return myMainPanel;
}
public void selectNotify() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
myProgressUpdatesQueue.showNotify();
if (myFileEditor != null) {
myFileEditor.selectNotify();
}
}
});
}
public void deselectNotify() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
myProgressUpdatesQueue.hideNotify();
if (myFileEditor != null) {
myFileEditor.deselectNotify();
}
}
});
}
public void dispose() {
myVirtualFile.getFileInfo().removeDownloadingListener(myDownloadingListener);
myProgressUpdatesQueue.dispose();
if (myFileEditor != null) {
Disposer.dispose(myFileEditor);
}
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
myDispatcher.addListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
myDispatcher.removeListener(listener);
}
public void propertyChange(PropertyChangeEvent evt) {
myDispatcher.getMulticaster().propertyChange(evt);
}
private class MyDownloadingListener implements FileDownloadingListener {
public void fileDownloaded(final VirtualFile localFile) {
switchEditor();
}
public void downloadingCancelled() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
if (myFileEditor != null) {
showCard(EDITOR_CARD);
}
else {
myErrorLabel.setText("Downloading cancelled");
showCard(ERROR_CARD);
}
}
});
}
public void downloadingStarted() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
showCard(DOWNLOADING_CARD);
}
});
}
public void errorOccurred(@NotNull final String errorMessage) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
myErrorLabel.setText(errorMessage);
showCard(ERROR_CARD);
}
});
}
public void progressMessageChanged(final boolean indeterminate, @NotNull final String message) {
myProgressUpdatesQueue.queue(new Update("progress text") {
public void run() {
myProgressLabel.setText(message);
}
});
}
public void progressFractionChanged(final double fraction) {
myProgressUpdatesQueue.queue(new Update("fraction") {
public void run() {
myProgressBar.setValue((int)Math.round(100*fraction));
}
});
}
}
}