df6c8403bfd99ed1507c45e555c0679669be5bad
[idea/community.git] / platform / platform-impl / src / com / intellij / openapi / fileEditor / ex / FileEditorManagerEx.java
1 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.openapi.fileEditor.ex;
3
4 import com.intellij.openapi.Disposable;
5 import com.intellij.openapi.editor.Caret;
6 import com.intellij.openapi.editor.Editor;
7 import com.intellij.openapi.fileEditor.EditorDataProvider;
8 import com.intellij.openapi.fileEditor.FileEditor;
9 import com.intellij.openapi.fileEditor.FileEditorManager;
10 import com.intellij.openapi.fileEditor.FileEditorProvider;
11 import com.intellij.openapi.fileEditor.impl.EditorComposite;
12 import com.intellij.openapi.fileEditor.impl.EditorWindow;
13 import com.intellij.openapi.fileEditor.impl.EditorsSplitters;
14 import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
15 import com.intellij.openapi.fileEditor.impl.text.AsyncEditorLoader;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.util.ActionCallback;
18 import com.intellij.openapi.util.BusyObject;
19 import com.intellij.openapi.util.Disposer;
20 import com.intellij.openapi.util.Pair;
21 import com.intellij.openapi.vfs.VirtualFile;
22 import org.jetbrains.annotations.NotNull;
23 import org.jetbrains.annotations.Nullable;
24 import org.jetbrains.concurrency.Promise;
25
26 import javax.swing.*;
27 import java.awt.*;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.Set;
31
32 public abstract class FileEditorManagerEx extends FileEditorManager implements BusyObject {
33   private final List<EditorDataProvider> myDataProviders = new ArrayList<>();
34
35   public static FileEditorManagerEx getInstanceEx(@NotNull Project project) {
36     return (FileEditorManagerEx)getInstance(project);
37   }
38
39   /**
40    * @return {@code JComponent} which represent the place where all editors are located
41    */
42   public abstract JComponent getComponent();
43
44   /**
45    * @return preferred focused component inside myEditor tabbed container.
46    * This method does similar things like {@link FileEditor#getPreferredFocusedComponent()}
47    * but it also tracks (and remember) focus movement inside tabbed container.
48    *
49    * @see EditorComposite#getPreferredFocusedComponent()
50    */
51   @Nullable
52   public abstract JComponent getPreferredFocusedComponent();
53
54   @NotNull
55   public abstract Pair<FileEditor[], FileEditorProvider[]> getEditorsWithProviders(@NotNull VirtualFile file);
56
57   @Nullable
58   public abstract VirtualFile getFile(@NotNull FileEditor editor);
59
60   /**
61    * Refreshes the text, colors and icon of the editor tabs representing the specified file.
62    *
63    * @param file the file to refresh.
64    */
65   public abstract void updateFilePresentation(@NotNull VirtualFile file);
66
67   /**
68    * Synchronous version of {@link #getActiveWindow()}. Will return {@code null} if invoked not from EDT.
69    * @return current window in splitters
70    */
71   public abstract EditorWindow getCurrentWindow();
72
73   /**
74    * Asynchronous version of {@link #getCurrentWindow()}. Execution happens after focus settle down. Can be invoked on any thread.
75    */
76   @NotNull
77   public abstract Promise<EditorWindow> getActiveWindow();
78
79   public abstract void setCurrentWindow(EditorWindow window);
80
81   /**
82    * Closes editors for the file opened in particular window.
83    *
84    * @param file file to be closed. Cannot be null.
85    */
86   public abstract void closeFile(@NotNull VirtualFile file, @NotNull EditorWindow window);
87
88   public abstract void unsplitWindow();
89
90   public abstract void unsplitAllWindow();
91
92   public abstract int getWindowSplitCount();
93
94   public abstract boolean hasSplitOrUndockedWindows();
95
96   public abstract EditorWindow @NotNull [] getWindows();
97
98   /**
99    * @return arrays of all files (including {@code file} itself) that belong
100    * to the same tabbed container. The method returns empty array if {@code file}
101    * is not open. The returned files have the same order as they have in the
102    * tabbed container.
103    */
104   public abstract VirtualFile @NotNull [] getSiblings(@NotNull VirtualFile file);
105
106   public abstract void createSplitter(int orientation, @Nullable EditorWindow window);
107
108   public abstract void changeSplitterOrientation();
109
110   public abstract boolean isInSplitter();
111
112   public abstract boolean hasOpenedFile();
113
114   @Nullable
115   public abstract VirtualFile getCurrentFile();
116
117   @Nullable
118   public abstract FileEditorWithProvider getSelectedEditorWithProvider(@NotNull VirtualFile file);
119
120   /**
121    * Closes all files IN ACTIVE SPLITTER (window).
122    *
123    * @see com.intellij.ui.docking.DockManager#getContainers()
124    * @see com.intellij.ui.docking.DockContainer#closeAll()
125    */
126   public abstract void closeAllFiles();
127
128   @NotNull
129   public abstract EditorsSplitters getSplitters();
130
131   @Override
132   public FileEditor @NotNull [] openFile(@NotNull VirtualFile file, boolean focusEditor) {
133     return openFileWithProviders(file, focusEditor, false).getFirst();
134   }
135
136   @Override
137   public FileEditor @NotNull [] openFile(@NotNull VirtualFile file, boolean focusEditor, boolean searchForOpen) {
138     return openFileWithProviders(file, focusEditor, searchForOpen).getFirst();
139   }
140
141   @NotNull
142   public abstract Pair<FileEditor[],FileEditorProvider[]> openFileWithProviders(@NotNull VirtualFile file,
143                                                                                 boolean focusEditor,
144                                                                                 boolean searchForSplitter);
145
146   @NotNull
147   public abstract Pair<FileEditor[],FileEditorProvider[]> openFileWithProviders(@NotNull VirtualFile file,
148                                                                                 boolean focusEditor,
149                                                                                 @NotNull EditorWindow window);
150
151   public abstract boolean isChanged(@NotNull EditorComposite editor);
152
153   public abstract EditorWindow getNextWindow(@NotNull final EditorWindow window);
154
155   public abstract EditorWindow getPrevWindow(@NotNull final EditorWindow window);
156
157   public abstract boolean isInsideChange();
158
159   @Override
160   @Nullable
161   public final Object getData(@NotNull String dataId, @NotNull Editor editor, @NotNull Caret caret) {
162     for (final EditorDataProvider dataProvider : myDataProviders) {
163       final Object o = dataProvider.getData(dataId, editor, caret);
164       if (o != null) return o;
165     }
166     return null;
167   }
168
169   @Override
170   public void registerExtraEditorDataProvider(@NotNull final EditorDataProvider provider, Disposable parentDisposable) {
171     myDataProviders.add(provider);
172     if (parentDisposable != null) {
173       Disposer.register(parentDisposable, () -> myDataProviders.remove(provider));
174     }
175   }
176
177   public void refreshIcons() {
178     if (this instanceof FileEditorManagerImpl) {
179       final FileEditorManagerImpl mgr = (FileEditorManagerImpl)this;
180       Set<EditorsSplitters> splitters = mgr.getAllSplitters();
181       for (EditorsSplitters each : splitters) {
182         for (VirtualFile file : mgr.getOpenFiles()) {
183           each.updateFileIcon(file);
184         }
185       }
186     }
187   }
188
189   public abstract EditorsSplitters getSplittersFor(Component c);
190
191
192   @NotNull
193   public abstract ActionCallback notifyPublisher(@NotNull Runnable runnable);
194
195   @Override
196   public void runWhenLoaded(@NotNull Editor editor, @NotNull Runnable runnable) {
197     AsyncEditorLoader.performWhenLoaded(editor, runnable);
198   }
199 }