27c218607988401b753675350c8425603310fa93
[idea/community.git] / platform / platform-api / src / com / intellij / openapi / fileEditor / FileEditorManager.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;
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.project.Project;
8 import com.intellij.openapi.util.Key;
9 import com.intellij.openapi.vfs.VirtualFile;
10 import org.jetbrains.annotations.ApiStatus;
11 import org.jetbrains.annotations.NotNull;
12 import org.jetbrains.annotations.Nullable;
13
14 import javax.swing.*;
15 import java.util.List;
16
17 public abstract class FileEditorManager {
18
19   public static final Key<Boolean> USE_CURRENT_WINDOW = Key.create("OpenFile.searchForOpen");
20
21   public static FileEditorManager getInstance(@NotNull Project project) {
22     return project.getComponent(FileEditorManager.class);
23   }
24
25   /**
26    * @param file file to open. File should be valid.
27    *             Must be called from <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">EDT</a>.
28    * @return array of opened editors
29    */
30   public abstract FileEditor @NotNull [] openFile(@NotNull VirtualFile file, boolean focusEditor);
31
32
33   /**
34    * Opens a file.
35    * Must be called from <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">EDT</a>.
36    *
37    * @param file        file to open
38    * @param focusEditor {@code true} if need to focus
39    * @return array of opened editors
40    */
41   public FileEditor @NotNull [] openFile(@NotNull VirtualFile file, boolean focusEditor, boolean searchForOpen) {
42     throw new UnsupportedOperationException("Not implemented");
43   }
44
45   /**
46    * Closes all editors opened for the file.
47    * Must be called from <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">EDT</a>.
48    *
49    * @param file file to be closed.
50    */
51   public abstract void closeFile(@NotNull VirtualFile file);
52
53   /**
54    * Works as {@link #openFile(VirtualFile, boolean)} but forces opening of text editor (see {@link TextEditor}).
55    * If several text editors are opened, including the default one, default text editor is focused (if requested) and returned.
56    * Must be called from <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">EDT</a>.
57    *
58    * @return opened text editor. The method returns {@code null} in case if text editor wasn't opened.
59    */
60   @Nullable
61   public abstract Editor openTextEditor(@NotNull OpenFileDescriptor descriptor, boolean focusEditor);
62
63   /**
64    * @deprecated use {@link #openTextEditor(OpenFileDescriptor, boolean)}
65    */
66   @Deprecated
67   public void navigateToTextEditor(@NotNull OpenFileDescriptor descriptor, boolean focusEditor) {
68     openTextEditor(descriptor, focusEditor);
69   }
70
71   /**
72    * @return currently selected text editor. The method returns {@code null} in case
73    * there is no selected editor at all or selected editor is not a text one.
74    * Must be called from <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">EDT</a>.
75    */
76   @Nullable
77   public abstract Editor getSelectedTextEditor();
78
79   /**
80    * @return currently selected TEXT editors including ones which were opened by guests during a collaborative development session
81    * The method returns an empty array in case there are no selected editors or none of them is a text one.
82    * Must be called from <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">EDT</a>.
83    */
84   @ApiStatus.Experimental
85   public Editor @NotNull [] getSelectedTextEditorWithRemotes() {
86     Editor editor = getSelectedTextEditor();
87     return editor != null ? new Editor[]{editor} : Editor.EMPTY_ARRAY;
88   }
89
90   /**
91    * @return {@code true} if {@code file} is opened, {@code false} otherwise
92    */
93   public abstract boolean isFileOpen(@NotNull VirtualFile file);
94
95   /**
96    * @return all opened files. Order of files in the array corresponds to the order of editor tabs.
97    */
98   public abstract VirtualFile @NotNull [] getOpenFiles();
99
100   public boolean hasOpenFiles() {
101     return getOpenFiles().length > 0;
102   }
103
104   /**
105    * @return files currently selected. The method returns empty array if there are no selected files.
106    * If more than one file is selected (split), the file with most recent focused editor is returned first.
107    */
108   public abstract VirtualFile @NotNull [] getSelectedFiles();
109
110   /**
111    * @return editors currently selected. The method returns empty array if no editors are open.
112    */
113   public abstract FileEditor @NotNull [] getSelectedEditors();
114
115   /**
116    * @return editors currently selected including ones which were opened by guests during a collaborative development session
117    * The method returns an empty array if no editors are open.
118    */
119   @ApiStatus.Experimental
120   public FileEditor @NotNull [] getSelectedEditorWithRemotes() {
121     return getSelectedEditors();
122   }
123
124   /**
125    * @return currently selected file editor or {@code null} if there is no selected editor at all.
126    */
127   @Nullable
128   public FileEditor getSelectedEditor() {
129     VirtualFile[] files = getSelectedFiles();
130     return files.length == 0 ? null : getSelectedEditor(files[0]);
131   }
132
133   /**
134    * @return editor which is currently selected for given file.
135    * The method returns {@code null} if {@code file} is not opened.
136    */
137   @Nullable
138   public abstract FileEditor getSelectedEditor(@NotNull VirtualFile file);
139
140   /**
141    * @return current editors for the specified {@code file}
142    */
143   public abstract FileEditor @NotNull [] getEditors(@NotNull VirtualFile file);
144
145   /**
146    * @return all editors for the specified {@code file}
147    */
148   public abstract FileEditor @NotNull [] getAllEditors(@NotNull VirtualFile file);
149
150   /**
151    * @return all open editors
152    */
153   public abstract FileEditor @NotNull [] getAllEditors();
154
155   /**
156    * Adds the specified component above the editor and paints a separator line below it.
157    * If a separator line is not needed, set the client property to {@code true}:
158    * <pre>    component.putClientProperty(SEPARATOR_DISABLED, true);    </pre>
159    * Otherwise, a separator line will be painted by a
160    * {@link com.intellij.openapi.editor.colors.EditorColors#SEPARATOR_ABOVE_COLOR SEPARATOR_ABOVE_COLOR} or
161    * {@link com.intellij.openapi.editor.colors.EditorColors#TEARLINE_COLOR TEARLINE_COLOR} if it is not set.
162    * <p>
163    * This method allows to add several components above the editor.
164    * To change an order of components the specified component may implement the
165    * {@link com.intellij.openapi.util.Weighted Weighted} interface.
166    */
167   public abstract void addTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component);
168
169   public abstract void removeTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component);
170
171   /**
172    * Adds the specified component below the editor and paints a separator line above it.
173    * If a separator line is not needed, set the client property to {@code true}:
174    * <pre>    component.putClientProperty(SEPARATOR_DISABLED, true);    </pre>
175    * Otherwise, a separator line will be painted by a
176    * {@link com.intellij.openapi.editor.colors.EditorColors#SEPARATOR_BELOW_COLOR SEPARATOR_BELOW_COLOR} or
177    * {@link com.intellij.openapi.editor.colors.EditorColors#TEARLINE_COLOR TEARLINE_COLOR} if it is not set.
178    * <p>
179    * This method allows to add several components below the editor.
180    * To change an order of components the specified component may implement the
181    * {@link com.intellij.openapi.util.Weighted Weighted} interface.
182    */
183   public abstract void addBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component);
184
185   public abstract void removeBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component);
186
187   public static final Key<Boolean> SEPARATOR_DISABLED = Key.create("FileEditorSeparatorDisabled");
188
189   /**
190    * Adds specified {@code listener}
191    *
192    * @param listener listener to be added
193    * @deprecated Use {@link com.intellij.util.messages.MessageBus} instead: see {@link FileEditorManagerListener#FILE_EDITOR_MANAGER}
194    */
195   @Deprecated
196   public void addFileEditorManagerListener(@NotNull FileEditorManagerListener listener) {
197   }
198
199   /**
200    * @deprecated Use {@link FileEditorManagerListener#FILE_EDITOR_MANAGER} instead
201    */
202   @Deprecated
203   public void addFileEditorManagerListener(@NotNull FileEditorManagerListener listener, @NotNull Disposable parentDisposable) {
204   }
205
206   /**
207    * Removes specified {@code listener}
208    *
209    * @param listener listener to be removed
210    * @deprecated Use {@link FileEditorManagerListener#FILE_EDITOR_MANAGER} instead
211    */
212   @Deprecated
213   public void removeFileEditorManagerListener(@NotNull FileEditorManagerListener listener) {
214   }
215
216   /**
217    * Must be called from <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">EDT</a>.
218    *
219    * @return opened file editors
220    */
221   @NotNull
222   public abstract List<FileEditor> openEditor(@NotNull OpenFileDescriptor descriptor, boolean focusEditor);
223
224   /**
225    * Returns the project with which the file editor manager is associated.
226    *
227    * @return the project instance.
228    */
229   @NotNull
230   public abstract Project getProject();
231
232   public abstract void registerExtraEditorDataProvider(@NotNull EditorDataProvider provider, Disposable parentDisposable);
233
234   /**
235    * Returns data associated with given editor/caret context. Data providers are registered via
236    * {@link #registerExtraEditorDataProvider(EditorDataProvider, Disposable)} method.
237    */
238   @Nullable
239   public abstract Object getData(@NotNull String dataId, @NotNull Editor editor, @NotNull Caret caret);
240
241   /**
242    * Selects a specified file editor tab for the specified editor.
243    *
244    * @param file                 a file to switch the file editor tab for. The function does nothing if the file is not currently open in the editor.
245    * @param fileEditorProviderId the ID of the file editor to open; matches the return value of
246    *                             {@link FileEditorProvider#getEditorTypeId()}
247    */
248   public abstract void setSelectedEditor(@NotNull VirtualFile file, @NotNull String fileEditorProviderId);
249
250   /**
251    * {@link FileEditorManager} supports asynchronous opening of text editors, i.e. when one of 'openFile' methods returns, returned
252    * editor might not be fully initialized yet. This method allows to delay (if needed) execution of given runnable until editor is
253    * fully loaded.
254    */
255   public abstract void runWhenLoaded(@NotNull Editor editor, @NotNull Runnable runnable);
256 }