1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "documentmodel.h"
29 #include "editorarea.h"
30 #include "editormanager.h"
31 #include "editorview.h"
32 #include "ieditor.h"
33 #include "ieditorfactory.h"
34 
35 #include <coreplugin/idocument.h>
36 
37 #include <QList>
38 #include <QObject>
39 #include <QPointer>
40 #include <QSet>
41 #include <QString>
42 #include <QVariant>
43 
44 QT_BEGIN_NAMESPACE
45 class QAction;
46 class QTimer;
47 QT_END_NAMESPACE
48 
49 namespace Core {
50 
51 class EditorManager;
52 
53 namespace Internal {
54 
55 class EditorWindow;
56 class MainWindow;
57 class OpenEditorsViewFactory;
58 class OpenEditorsWindow;
59 
60 enum MakeWritableResult { OpenedWithVersionControl, MadeWritable, SavedAs, Failed };
61 
62 class EditorManagerPrivate : public QObject
63 {
64     Q_OBJECT
65 
66     friend class Core::EditorManager;
67 
68 public:
69     enum class CloseFlag {
70         CloseWithAsking,
71         CloseWithoutAsking,
72         Suspend
73     };
74 
75     static EditorManagerPrivate *instance();
76 
77     static void extensionsInitialized(); // only use from MainWindow
78 
79     static EditorArea *mainEditorArea();
80     static EditorView *currentEditorView();
81     static void setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory = false);
82     static IEditor *openEditor(EditorView *view,
83                                const Utils::FilePath &filePath,
84                                Utils::Id editorId = {},
85                                EditorManager::OpenEditorFlags flags = EditorManager::NoFlags,
86                                bool *newEditor = nullptr);
87     static IEditor *openEditorAt(EditorView *view,
88                                  const Utils::Link &filePath,
89                                  Utils::Id editorId = {},
90                                  EditorManager::OpenEditorFlags flags = EditorManager::NoFlags,
91                                  bool *newEditor = nullptr);
92     static IEditor *openEditorWith(const Utils::FilePath &filePath, Utils::Id editorId);
93     static IEditor *duplicateEditor(IEditor *editor);
94     static IEditor *activateEditor(EditorView *view, IEditor *editor,
95                                    EditorManager::OpenEditorFlags flags = EditorManager::NoFlags);
96     static IEditor *activateEditorForDocument(EditorView *view, IDocument *document,
97                                               EditorManager::OpenEditorFlags flags = {});
98     static bool activateEditorForEntry(EditorView *view, DocumentModel::Entry *entry,
99                                        EditorManager::OpenEditorFlags flags = EditorManager::NoFlags);
100     /* closes the document if there is no other editor on the document visible */
101     static void closeEditorOrDocument(IEditor *editor);
102     static bool closeEditors(const QList<IEditor *> &editors, CloseFlag flag);
103 
104     static EditorView *viewForEditor(IEditor *editor);
105     static void setCurrentView(EditorView *view);
106     static void activateView(EditorView *view);
107 
108     static MakeWritableResult makeFileWritable(IDocument *document);
109     static void doEscapeKeyFocusMoveMagic();
110 
111     static Utils::Id getOpenWithEditorId(const QString &fileName, bool *isExternalEditor = nullptr);
112 
113     static void saveSettings();
114     static void readSettings();
115     static void setAutoSaveEnabled(bool enabled);
116     static bool autoSaveEnabled();
117     static void setAutoSaveInterval(int interval);
118     static int autoSaveInterval();
119     static void setAutoSuspendEnabled(bool enabled);
120     static bool autoSuspendEnabled();
121     static void setAutoSuspendMinDocumentCount(int count);
122     static int autoSuspendMinDocumentCount();
123     static void setWarnBeforeOpeningBigFilesEnabled(bool enabled);
124     static bool warnBeforeOpeningBigFilesEnabled();
125     static void setBigFileSizeLimit(int limitInMB);
126     static int bigFileSizeLimit();
127     static void setMaxRecentFiles(int count);
128     static int maxRecentFiles();
129 
130     static EditorWindow *createEditorWindow();
131     static void splitNewWindow(Internal::EditorView *view);
132     static void closeView(Internal::EditorView *view);
133     static const QList<IEditor *> emptyView(Internal::EditorView *view);
134     static void deleteEditors(const QList<IEditor *> &editors);
135 
136     static void updateActions();
137 
138     static void updateWindowTitleForDocument(IDocument *document, QWidget *window);
139 
140     static void vcsOpenCurrentEditor();
141     static void makeCurrentEditorWritable();
142 
143     static void setPlaceholderText(const QString &text);
144     static QString placeholderText();
145 
146 public slots:
147     static bool saveDocument(Core::IDocument *document);
148     static bool saveDocumentAs(Core::IDocument *document);
149 
150     static void split(Qt::Orientation orientation);
151     static void removeAllSplits();
152     static void gotoPreviousSplit();
153     static void gotoNextSplit();
154 
155     void handleDocumentStateChange();
156     void editorAreaDestroyed(QObject *area);
157 
158 signals:
159     void placeholderTextChanged(const QString &text);
160 
161 private:
162     static void gotoNextDocHistory();
163     static void gotoPreviousDocHistory();
164 
165     static void gotoLastEditLocation();
166 
167     static void autoSave();
168     static void handleContextChange(const QList<Core::IContext *> &context);
169 
170     static void copyFilePathFromContextMenu();
171     void copyLocationFromContextMenu();
172     static void copyFileNameFromContextMenu();
173     static void saveDocumentFromContextMenu();
174     static void saveDocumentAsFromContextMenu();
175     static void revertToSavedFromContextMenu();
176     static void closeEditorFromContextMenu();
177     static void closeOtherDocumentsFromContextMenu();
178 
179     static void closeAllEditorsExceptVisible();
180     static void revertToSaved(IDocument *document);
181     static void autoSuspendDocuments();
182 
183     static void openTerminal();
184     static void findInDirectory();
185 
186     static void togglePinned();
187 
188     static void removeCurrentSplit();
189 
190     static void setCurrentEditorFromContextChange();
191 
192     static OpenEditorsWindow *windowPopup();
193     static void showPopupOrSelectDocument();
194 
195     static EditorFactoryList findFactories(Utils::Id editorId, const QString &fileName);
196     static IEditor *createEditor(IEditorFactory *factory, const QString &fileName);
197     static void addEditor(IEditor *editor);
198     static void removeEditor(IEditor *editor, bool removeSusependedEntry);
199     static IEditor *placeEditor(EditorView *view, IEditor *editor);
200     static void restoreEditorState(IEditor *editor);
201     static int visibleDocumentsCount();
202     static EditorArea *findEditorArea(const EditorView *view, int *areaIndex = nullptr);
203     static IEditor *pickUnusedEditor(Internal::EditorView **foundView = nullptr);
204     static void addDocumentToRecentFiles(IDocument *document);
205     static void updateAutoSave();
206     static void updateMakeWritableWarning();
207     static void setupSaveActions(IDocument *document, QAction *saveAction,
208                                  QAction *saveAsAction, QAction *revertToSavedAction);
209     static void updateWindowTitle();
210     static bool skipOpeningBigTextFile(const Utils::FilePath &filePath);
211 
212 private:
213     explicit EditorManagerPrivate(QObject *parent);
214     ~EditorManagerPrivate() override;
215     void init();
216 
217     EditLocation m_globalLastEditLocation;
218     QList<EditLocation> m_globalHistory;
219     QList<EditorArea *> m_editorAreas;
220     QPointer<IEditor> m_currentEditor;
221     QPointer<IEditor> m_scheduledCurrentEditor;
222     QPointer<EditorView> m_currentView;
223     QTimer *m_autoSaveTimer = nullptr;
224 
225     // actions
226     QAction *m_revertToSavedAction;
227     QAction *m_saveAction;
228     QAction *m_saveAsAction;
229     QAction *m_closeCurrentEditorAction;
230     QAction *m_closeAllEditorsAction;
231     QAction *m_closeOtherDocumentsAction;
232     QAction *m_closeAllEditorsExceptVisibleAction;
233     QAction *m_gotoNextDocHistoryAction;
234     QAction *m_gotoPreviousDocHistoryAction;
235     QAction *m_goBackAction;
236     QAction *m_goForwardAction;
237     QAction *m_gotoLastEditAction;
238     QAction *m_splitAction;
239     QAction *m_splitSideBySideAction;
240     QAction *m_splitNewWindowAction;
241     QAction *m_removeCurrentSplitAction;
242     QAction *m_removeAllSplitsAction;
243     QAction *m_gotoPreviousSplitAction;
244     QAction *m_gotoNextSplitAction;
245 
246     QAction *m_copyFilePathContextAction;
247     QAction *m_copyLocationContextAction; // Copy path and line number.
248     QAction *m_copyFileNameContextAction;
249     QAction *m_saveCurrentEditorContextAction;
250     QAction *m_saveAsCurrentEditorContextAction;
251     QAction *m_revertToSavedCurrentEditorContextAction;
252 
253     QAction *m_closeCurrentEditorContextAction;
254     QAction *m_closeAllEditorsContextAction;
255     QAction *m_closeOtherDocumentsContextAction;
256     QAction *m_closeAllEditorsExceptVisibleContextAction;
257     QAction *m_openGraphicalShellAction;
258     QAction *m_openGraphicalShellContextAction;
259     QAction *m_openTerminalAction;
260     QAction *m_findInDirectoryAction;
261     QAction *m_filePropertiesAction = nullptr;
262     QAction *m_pinAction = nullptr;
263     DocumentModel::Entry *m_contextMenuEntry = nullptr;
264     IEditor *m_contextMenuEditor = nullptr;
265 
266     OpenEditorsWindow *m_windowPopup = nullptr;
267 
268     QMap<QString, QVariant> m_editorStates;
269     OpenEditorsViewFactory *m_openEditorsFactory = nullptr;
270 
271     EditorManager::WindowTitleHandler m_titleAdditionHandler;
272     EditorManager::WindowTitleHandler m_sessionTitleHandler;
273     EditorManager::WindowTitleHandler m_titleVcsTopicHandler;
274 
275     struct Settings
276     {
277         IDocument::ReloadSetting reloadSetting = IDocument::AlwaysAsk;
278 
279         bool autoSaveEnabled = true;
280         int autoSaveInterval = 5;
281 
282         bool autoSuspendEnabled = true;
283         int autoSuspendMinDocumentCount = 30;
284 
285         bool warnBeforeOpeningBigFilesEnabled = true;
286         int bigFileSizeLimitInMB = 5;
287         int maxRecentFiles = 8;
288     };
289 
290     Settings m_settings;
291     QString m_placeholderText;
292     QList<std::function<bool(IEditor *)>> m_closeEditorListeners;
293 };
294 
295 } // Internal
296 } // Core
297