1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 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 "../core_global.h"
29 #include "../idocument.h"
30 
31 #include "documentmodel.h"
32 #include "ieditor.h"
33 
34 #include "utils/link.h"
35 #include "utils/textfileformat.h"
36 
37 #include <QList>
38 #include <QWidget>
39 
40 #include <functional>
41 
QT_FORWARD_DECLARE_CLASS(QMenu)42 QT_FORWARD_DECLARE_CLASS(QMenu)
43 
44 namespace Utils {
45 class MimeType;
46 }
47 
48 namespace Core {
49 
50 class IDocument;
51 class SearchResultItem;
52 
53 namespace Internal {
54 class EditorManagerPrivate;
55 class MainWindow;
56 } // namespace Internal
57 
58 class CORE_EXPORT EditorManagerPlaceHolder final : public QWidget
59 {
60     Q_OBJECT
61 public:
62     explicit EditorManagerPlaceHolder(QWidget *parent = nullptr);
63     ~EditorManagerPlaceHolder() final;
64 
65 protected:
66     void showEvent(QShowEvent *event) override;
67 };
68 
69 class CORE_EXPORT EditorManager : public QObject
70 {
71     Q_OBJECT
72 
73 public:
74     using WindowTitleHandler = std::function<QString (const QString &)>;
75 
76     static EditorManager *instance();
77 
78     enum OpenEditorFlag {
79         NoFlags = 0,
80         DoNotChangeCurrentEditor = 1,
81         IgnoreNavigationHistory = 2,
82         DoNotMakeVisible = 4,
83         OpenInOtherSplit = 8,
84         DoNotSwitchToDesignMode = 16,
85         DoNotSwitchToEditMode = 32,
86         SwitchSplitIfAlreadyVisible = 64,
87         DoNotRaise = 128
88     };
89     Q_DECLARE_FLAGS(OpenEditorFlags, OpenEditorFlag)
90 
91     static IEditor *openEditor(const Utils::FilePath &filePath,
92                                Utils::Id editorId = {},
93                                OpenEditorFlags flags = NoFlags,
94                                bool *newEditor = nullptr);
95     static IEditor *openEditorAt(const Utils::Link &link,
96                                  Utils::Id editorId = {},
97                                  OpenEditorFlags flags = NoFlags,
98                                  bool *newEditor = nullptr);
99 
100     // Kept for a while for transition.
101     static IEditor *openEditor(const QString &fileName, Utils::Id editorId = {},
102         OpenEditorFlags flags = NoFlags, bool *newEditor = nullptr); // FIXME: Remove overload
103     static IEditor *openEditorAt(const QString &fileName,  int line, int column = 0,
104                                  Utils::Id editorId = {}, OpenEditorFlags flags = NoFlags,
105                                  bool *newEditor = nullptr); // FIXME: Remove overload
106 
107     static void openEditorAtSearchResult(const SearchResultItem &item,
108                                          Utils::Id editorId = {},
109                                          OpenEditorFlags flags = NoFlags,
110                                          bool *newEditor = nullptr);
111     static IEditor *openEditorWithContents(Utils::Id editorId, QString *titlePattern = nullptr,
112                                            const QByteArray &contents = QByteArray(),
113                                            const QString &uniqueId = QString(),
114                                            OpenEditorFlags flags = NoFlags);
115     static bool skipOpeningBigTextFile(const Utils::FilePath &filePath);
116     static void clearUniqueId(IDocument *document);
117 
118     static bool openExternalEditor(const Utils::FilePath &filePath, Utils::Id editorId);
119     static void addCloseEditorListener(const std::function<bool(IEditor *)> &listener);
120 
121     static QStringList getOpenFileNames();
122 
123     static IDocument *currentDocument();
124     static IEditor *currentEditor();
125     static QList<IEditor *> visibleEditors();
126 
127     static void activateEditor(IEditor *editor, OpenEditorFlags flags = NoFlags);
128     static void activateEditorForEntry(DocumentModel::Entry *entry, OpenEditorFlags flags = NoFlags);
129     static IEditor *activateEditorForDocument(IDocument *document, OpenEditorFlags flags = NoFlags);
130 
131     static bool closeDocuments(const QList<IDocument *> &documents, bool askAboutModifiedEditors = true);
132     static bool closeDocuments(const QList<DocumentModel::Entry *> &entries);
133     static void closeOtherDocuments(IDocument *document);
134     static bool closeAllDocuments();
135 
136     static void addCurrentPositionToNavigationHistory(const QByteArray &saveState = QByteArray());
137     static void setLastEditLocation(const IEditor *editor);
138     static void cutForwardNavigationHistory();
139 
140     static bool saveDocument(IDocument *document);
141 
142     static bool closeEditors(const QList<IEditor *> &editorsToClose, bool askAboutModifiedEditors = true);
143 
144     static QByteArray saveState();
145     static bool restoreState(const QByteArray &state);
146     static bool hasSplitter();
147 
148     static void showEditorStatusBar(const QString &id,
149                                     const QString &infoText,
150                                     const QString &buttonText = QString(),
151                                     QObject *object = nullptr,
152                                     const std::function<void()> &function = {});
153     static void hideEditorStatusBar(const QString &id);
154 
155     static bool isAutoSaveFile(const QString &fileName);
156 
157     static QTextCodec *defaultTextCodec();
158 
159     static Utils::TextFileFormat::LineTerminationMode defaultLineEnding();
160 
161     static qint64 maxTextFileSize();
162 
163     static void setWindowTitleAdditionHandler(WindowTitleHandler handler);
164     static void setSessionTitleHandler(WindowTitleHandler handler);
165     static void setWindowTitleVcsTopicHandler(WindowTitleHandler handler);
166 
167     static void addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentModel::Entry *entry,
168                                              IEditor *editor = nullptr);
169     static void addPinEditorActions(QMenu *contextMenu, DocumentModel::Entry *entry);
170     static void addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentModel::Entry *entry);
171     static void populateOpenWithMenu(QMenu *menu, const QString &fileName);
172 
173 public: // for tests
174     static IDocument::ReloadSetting reloadSetting();
175     static void setReloadSetting(IDocument::ReloadSetting behavior);
176 
177 signals:
178     void currentEditorChanged(Core::IEditor *editor);
179     void currentDocumentStateChanged();
180     void documentStateChanged(Core::IDocument *document);
181     void editorCreated(Core::IEditor *editor, const QString &fileName);
182     void editorOpened(Core::IEditor *editor);
183     void documentOpened(Core::IDocument *document);
184     void editorAboutToClose(Core::IEditor *editor);
185     void editorsClosed(QList<Core::IEditor *> editors);
186     void documentClosed(Core::IDocument *document);
187     void findOnFileSystemRequest(const QString &path);
188     void openFileProperties(const Utils::FilePath &path);
189     void aboutToSave(IDocument *document);
190     void saved(IDocument *document);
191     void autoSaved();
192     void currentEditorAboutToChange(Core::IEditor *editor);
193 
194 #ifdef WITH_TESTS
195     void linkOpened();
196 #endif
197 
198 public slots:
199     static void saveDocument();
200     static void saveDocumentAs();
201     static void revertToSaved();
202     static bool closeAllEditors(bool askAboutModifiedEditors = true);
203     static void slotCloseCurrentEditorOrDocument();
204     static void closeOtherDocuments();
205     static void splitSideBySide();
206     static void gotoOtherSplit();
207     static void goBackInNavigationHistory();
208     static void goForwardInNavigationHistory();
209     static void updateWindowTitles();
210 
211 private:
212     explicit EditorManager(QObject *parent);
213     ~EditorManager() override;
214 
215     friend class Core::Internal::MainWindow;
216 };
217 
218 } // namespace Core
219 
220 Q_DECLARE_OPERATORS_FOR_FLAGS(Core::EditorManager::OpenEditorFlags)
221