diff options
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/fileEditor/impl')
6 files changed, 318 insertions, 15 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index b1f9ec0c2b93..b9e38809faab 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -148,7 +148,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } - private boolean showEmptyText() { + protected boolean showEmptyText() { return myCurrentWindow == null || myCurrentWindow.getFiles().length == 0; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java index cce6de27545d..ec2559fc06ba 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -550,14 +550,18 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt if (document != null) { // a file is linked to a document - chances are it is an "unknown text file" now if (isBinaryWithoutDecompiler(file)) { - myDocuments.remove(file); - file.putUserData(HARD_REF_TO_DOCUMENT_KEY, null); - document.putUserData(FILE_KEY, null); + unbindFileFromDocument(file, document); } } } } + private void unbindFileFromDocument(@NotNull VirtualFile file, @NotNull Document document) { + myDocuments.remove(file); + file.putUserData(HARD_REF_TO_DOCUMENT_KEY, null); + document.putUserData(FILE_KEY, null); + } + private static boolean isBinaryWithDecompiler(@NotNull VirtualFile file) { final FileType ft = file.getFileType(); return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) != null; @@ -609,6 +613,13 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt return; } + if (file.getLength() > FileUtilRt.LARGE_FOR_CONTENT_LOADING) { + unbindFileFromDocument(file, document); + myUnsavedDocuments.remove(document); + myMultiCaster.fileWithNoDocumentChanged(file); + return; + } + final Project project = ProjectLocator.getInstance().guessProjectForFile(file); CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override @@ -640,7 +651,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt public boolean process(final VirtualFile file, final Document document) { String message = UIBundle.message("file.cache.conflict.message.text", file.getPresentableUrl()); - final DialogBuilder builder = new DialogBuilder((Project)null); + final DialogBuilder builder = new DialogBuilder(); builder.setCenterPanel(new JLabel(message, Messages.getQuestionIcon(), SwingConstants.CENTER)); builder.addOkAction().setText(UIBundle.message("file.cache.conflict.load.fs.changes.button")); builder.addCancelAction().setText(UIBundle.message("file.cache.conflict.keep.memory.changes.button")); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index bab6d2b2fa4f..65adf52041b9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -58,6 +58,7 @@ import com.intellij.openapi.vcs.FileStatusListener; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.*; import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.StatusBarEx; @@ -90,6 +91,7 @@ import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; import java.util.*; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** * @author Anton Katilin @@ -106,10 +108,12 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec public static final String FILE_EDITOR_MANAGER = "FileEditorManager"; private volatile JPanel myPanels; + private PreviewPanel myPreviewPanel; private EditorsSplitters mySplitters; private final Project myProject; private final List<Pair<VirtualFile, EditorWindow>> mySelectionHistory = new ArrayList<Pair<VirtualFile, EditorWindow>>(); private WeakReference<EditorComposite> myLastSelectedComposite = new WeakReference<EditorComposite>(null); + private final AtomicBoolean myPreviewBlocker = new AtomicBoolean(false); private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null); @@ -174,7 +178,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } public Set<EditorsSplitters> getAllSplitters() { - HashSet<EditorsSplitters> all = new HashSet<EditorsSplitters>(); + HashSet<EditorsSplitters> all = new LinkedHashSet<EditorsSplitters>(); + if (Registry.is("editor.use.preview")) { + initUI(); + all.add(myPreviewPanel.getWindow().getOwner()); + } all.add(getMainSplitters()); Set<DockContainer> dockContainers = myDockManager.getContainers(); for (DockContainer each : dockContainers) { @@ -247,6 +255,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } } } + if (myPreviewPanel == null && Registry.is("editor.use.preview")) { + synchronized (myInitLock) { + myPreviewPanel = new PreviewPanel(myProject, this, myDockManager); + } + } } private static class MyBorder implements Border { @@ -595,7 +608,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec @NotNull public Pair<FileEditor[], FileEditorProvider[]> openFileWithProviders(@NotNull final VirtualFile file, final boolean focusEditor, - boolean searchForSplitter) { + final boolean searchForSplitter) { if (!file.isValid()) { throw new IllegalArgumentException("file is not valid: " + file); } @@ -628,6 +641,13 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec wndToOpenIn = getSplitters().getCurrentWindow(); } + if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) { + EditorWindow previewWindow = getPreviewWindow(file, focusEditor, searchForSplitter); + if (previewWindow != null) { + wndToOpenIn = previewWindow; + } + } + EditorsSplitters splitters = getSplitters(); if (wndToOpenIn == null) { @@ -638,6 +658,31 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec return openFileImpl2(wndToOpenIn, file, focusEditor); } + @Nullable + private EditorWindow getPreviewWindow(@NotNull VirtualFile virtualFile, final boolean focusEditor, final boolean searchForSplitter) { + EditorWindow wndToOpenIn = null; + if (Registry.is("editor.use.preview") && !myPreviewBlocker.get()) { + wndToOpenIn = myPreviewPanel.getWindow(); + if (virtualFile.equals(myPreviewPanel.getCurrentFile())) return wndToOpenIn; + final VirtualFile modifiedFile = myPreviewPanel.closeCurrentFile(); + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).activate(null, false); + if (modifiedFile != null) { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + @Override + public void run() { + myPreviewBlocker.set(true); + try { + openFileWithProviders(modifiedFile, focusEditor, searchForSplitter); + } finally { + myPreviewBlocker.set(false); + } + } + }, "", null); + } + } + return wndToOpenIn; + } + public Pair<FileEditor[], FileEditorProvider[]> openFileInNewWindow(@NotNull VirtualFile file) { return ((DockManagerImpl)DockManager.getInstance(getProject())).createNewDockContainerFor(file, this); } @@ -1610,7 +1655,10 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec return null; } - public void runChange(FileEditorManagerChange change, EditorsSplitters splitters) { + /** + * @param splitters - taken getAllSplitters() value if parameter is null + */ + public void runChange(@NotNull FileEditorManagerChange change, @Nullable EditorsSplitters splitters) { Set<EditorsSplitters> target = new HashSet<EditorsSplitters>(); if (splitters == null) { target.addAll(getAllSplitters()); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java new file mode 100644 index 000000000000..a9634d5a335a --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java @@ -0,0 +1,244 @@ +/* + * Copyright 2000-2014 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; + +import com.intellij.icons.AllIcons; +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.impl.ToolWindowImpl; +import com.intellij.ui.JBColor; +import com.intellij.ui.docking.DockManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +class PreviewPanel extends JPanel implements DocumentListener, FileEditorManagerListener.Before { + private static final int HISTORY_LIMIT = 10; + + private final Project myProject; + private final FileEditorManagerImpl myManager; + private final DockManager myDockManager; + private EditorWindow myWindow; + private boolean myInitialized = false; + private EditorsSplitters myEditorsSplitters; + private ArrayList<VirtualFile> myHistory = new ArrayList<VirtualFile>(); + private VirtualFile myModifiedFile = null; + private ToolWindowImpl myToolWindow; + private VirtualFile myAwaitingForOpen = null; + + public PreviewPanel(Project project, FileEditorManagerImpl manager, DockManager dockManager) { + myProject = project; + myManager = manager; + myDockManager = dockManager; + setOpaque(true); + setBackground(JBColor.DARK_GRAY); + } + + private void initToolWindowIfNeed() { + if (myInitialized) return; + + myToolWindow = (ToolWindowImpl)ToolWindowManager.getInstance(myProject) + .registerToolWindow(ToolWindowId.PREVIEW, this, ToolWindowAnchor.RIGHT, myProject, false); + myToolWindow.setIcon(AllIcons.Actions.PreviewDetails); + + myEditorsSplitters = new EditorsSplitters(myManager, myDockManager, false) { + @Override + public void updateFileName(VirtualFile updatedFile) { + super.updateFileName(updatedFile); + if (updatedFile != null && updatedFile.equals(getCurrentFile())) { + updateWindowTitle(updatedFile); + } + } + + @Override + protected void afterFileOpen(VirtualFile file) { + if (file.equals(myAwaitingForOpen)) { + updateWindowTitle(file); + Document document = FileDocumentManager.getInstance().getDocument(file); + if (document != null) { + myModifiedFile = null; + document.addDocumentListener(PreviewPanel.this, myProject); + } + } + myAwaitingForOpen = null; + } + + @Override + public void setTabsPlacement(int tabPlacement) { + super.setTabsPlacement(UISettings.TABS_NONE); + } + + @Override + protected boolean showEmptyText() { + return false; + } + }; + + myProject.getMessageBus().connect().subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, this); + myEditorsSplitters.createCurrentWindow(); + + myWindow = myEditorsSplitters.getCurrentWindow(); + myWindow.setTabsPlacement(UISettings.TABS_NONE); + + setLayout(new GridLayout(1, 1)); + add(myEditorsSplitters); + + myToolWindow.setTitleActions(new MoveToEditorTabsAction(), new CloseFileAction()); + + myInitialized = true; + } + + private void updateWindowTitle(VirtualFile file) { + if (myToolWindow == null) return; + if (file == null) { + myToolWindow.setTitle(": (empty)"); + } + else { + myToolWindow.setTitle(": " + + StringUtil.getShortened(EditorTabbedContainer.calcTabTitle(myProject, file), + UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT)); + } + } + + @Override + public void beforeFileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + myAwaitingForOpen = file; + } + + @Override + public void beforeFileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + if (file.equals(getCurrentFile())) { + updateWindowTitle(null); + Document document = FileDocumentManager.getInstance().getDocument(file); + if (document != null) { + document.removeDocumentListener(this); + } + } + } + + + @Override + public void beforeDocumentChange(DocumentEvent event) { + + } + + @Override + public void documentChanged(DocumentEvent event) { + VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument()); + if (file != null) { + myModifiedFile = file; + } + } + + EditorWindow getWindow() { + initToolWindowIfNeed(); + return myWindow; + } + + @Nullable + VirtualFile getCurrentFile() { + VirtualFile[] files = myWindow.getFiles(); + return files.length == 1 ? files[0] : null; + } + + private class MoveToEditorTabsAction extends AnAction { + public MoveToEditorTabsAction() { + super(null, "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed); + } + + @Override + public void actionPerformed(AnActionEvent e) { + VirtualFile virtualFile = getCurrentFile(); + if (virtualFile == null) { + return; + } + + myManager.openFileWithProviders(virtualFile, false, myManager.getCurrentWindow()); + closeCurrentFile(); + } + + @Override + public void update(AnActionEvent e) { + super.update(e); + VirtualFile currentFile = getCurrentFile(); + e.getPresentation().setEnabled(currentFile != null); + if (currentFile == null) return; + + if (isModified(currentFile)) { + e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeft); + } + else { + e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeftGrayed); + } + } + } + + private boolean isModified(@NotNull VirtualFile file) { + return file.equals(myModifiedFile); + } + + //returns last open file if it has "modified" status + @Nullable + VirtualFile closeCurrentFile() { + VirtualFile virtualFile = getCurrentFile(); + if (virtualFile == null) return null; + if (!myHistory.contains(virtualFile)) { + myHistory.add(virtualFile); + while (myHistory.size() > HISTORY_LIMIT) { + myHistory.remove(0); + } + } + myWindow.closeFile(virtualFile); + this.revalidate(); + this.repaint(); + return isModified(virtualFile) ? virtualFile : null; + } + + private class CloseFileAction extends AnAction { + public CloseFileAction() { + super(null, "Close", AllIcons.Actions.Close); + } + + @Override + public void actionPerformed(AnActionEvent e) { + if (getCurrentFile() == null) return; + closeCurrentFile(); + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null); + } + + @Override + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(getCurrentFile() != null); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java index b24927b70726..076d29e64bbe 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -32,7 +32,7 @@ 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.ui.AppUIUtil; -import com.intellij.util.net.HTTPProxySettingsDialog; +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; @@ -86,22 +86,22 @@ public class RemoteFilePanel { remoteFileInfo.addDownloadingListener(myDownloadingListener); myCancelButton.addActionListener(new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { + public void actionPerformed(@NotNull final ActionEvent e) { remoteFileInfo.cancelDownloading(); } }); myTryAgainButton.addActionListener(new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { + public void actionPerformed(@NotNull final ActionEvent e) { showCard(DOWNLOADING_CARD); remoteFileInfo.restartDownloading(); } }); myChangeProxySettingsButton.addActionListener(new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { - new HTTPProxySettingsDialog().show(); + public void actionPerformed(@NotNull ActionEvent e) { + HttpConfigurable.editConfigurable(myMainPanel); } }); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java index 690e7c7d2820..14f0c95ec31b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java @@ -287,7 +287,7 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware { new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN), new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN))); } - caretModel.setCaretsAndSelections(states); + caretModel.setCaretsAndSelections(states, false); } else { LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN); |