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 <coreplugin/core_global.h>
29 
30 #include <utils/fileutils.h>
31 #include <utils/id.h>
32 
33 #include <QObject>
34 #include <QPair>
35 
36 namespace Utils { class FilePath; }
37 
38 namespace Core {
39 
40 class IDocument;
41 
42 namespace Internal {
43 class DocumentManagerPrivate;
44 class MainWindow;
45 }
46 
47 class CORE_EXPORT DocumentManager : public QObject
48 {
49     Q_OBJECT
50 public:
51     enum ResolveMode {
52         ResolveLinks,
53         KeepLinks
54     };
55 
56     using RecentFile = QPair<Utils::FilePath, Utils::Id>;
57 
58     static DocumentManager *instance();
59 
60     // file pool to monitor
61     static void addDocuments(const QList<IDocument *> &documents, bool addWatcher = true);
62     static void addDocument(IDocument *document, bool addWatcher = true);
63     static bool removeDocument(IDocument *document);
64     static QList<IDocument *> modifiedDocuments();
65 
66     static void renamedFile(const Utils::FilePath &from, const Utils::FilePath &to);
67 
68     static void expectFileChange(const Utils::FilePath &filePath);
69     static void unexpectFileChange(const Utils::FilePath &filePath);
70 
71     // recent files
72     static void addToRecentFiles(const Utils::FilePath &filePath, Utils::Id editorId = {});
73     Q_SLOT void clearRecentFiles();
74     static QList<RecentFile> recentFiles();
75 
76     static void saveSettings();
77 
78     // helper functions
79     static Utils::FilePath filePathKey(const Utils::FilePath &filePath, ResolveMode resolveMode);
80 
81     static bool saveDocument(IDocument *document,
82                              const Utils::FilePath &filePath = Utils::FilePath(),
83                              bool *isReadOnly = nullptr);
84 
85     static QString allDocumentFactoryFiltersString(QString *allFilesFilter);
86 
87     static QStringList getOpenFileNames(const QString &filters,
88                                         const QString &path = QString(),
89                                         QString *selectedFilter = nullptr);
90     static QString getSaveFileName(const QString &title,
91                                    const QString &pathIn,
92                                    const QString &filter = QString(),
93                                    QString *selectedFilter = nullptr);
94     static QString getSaveFileNameWithExtension(const QString &title, const QString &pathIn,
95                                          const QString &filter);
96     static QString getSaveAsFileName(const IDocument *document);
97 
98     static bool saveAllModifiedDocumentsSilently(bool *canceled = nullptr,
99                                                  QList<IDocument *> *failedToClose = nullptr);
100     static bool saveModifiedDocumentsSilently(const QList<IDocument *> &documents,
101                                               bool *canceled = nullptr,
102                                               QList<IDocument *> *failedToClose = nullptr);
103     static bool saveModifiedDocumentSilently(IDocument *document,
104                                              bool *canceled = nullptr,
105                                              QList<IDocument *> *failedToClose = nullptr);
106 
107     static bool saveAllModifiedDocuments(const QString &message = QString(),
108                                          bool *canceled = nullptr,
109                                          const QString &alwaysSaveMessage = QString(),
110                                          bool *alwaysSave = nullptr,
111                                          QList<IDocument *> *failedToClose = nullptr);
112     static bool saveModifiedDocuments(const QList<IDocument *> &documents,
113                                       const QString &message = QString(),
114                                       bool *canceled = nullptr,
115                                       const QString &alwaysSaveMessage = QString(),
116                                       bool *alwaysSave = nullptr,
117                                       QList<IDocument *> *failedToClose = nullptr);
118     static bool saveModifiedDocument(IDocument *document,
119                                      const QString &message = QString(),
120                                      bool *canceled = nullptr,
121                                      const QString &alwaysSaveMessage = QString(),
122                                      bool *alwaysSave = nullptr,
123                                      QList<IDocument *> *failedToClose = nullptr);
124     static void showFilePropertiesDialog(const Utils::FilePath &filePath);
125 
126     static QString fileDialogLastVisitedDirectory();
127     static void setFileDialogLastVisitedDirectory(const QString &);
128 
129     static QString fileDialogInitialDirectory();
130 
131     static QString defaultLocationForNewFiles();
132     static void setDefaultLocationForNewFiles(const QString &location);
133 
134     static bool useProjectsDirectory();
135     static void setUseProjectsDirectory(bool);
136 
137     static Utils::FilePath projectsDirectory();
138     static void setProjectsDirectory(const Utils::FilePath &directory);
139 
140     /* Used to notify e.g. the code model to update the given files. Does *not*
141        lead to any editors to reload or any other editor manager actions. */
142     static void notifyFilesChangedInternally(const Utils::FilePaths &filePaths);
143 
144 signals:
145     /* Used to notify e.g. the code model to update the given files. Does *not*
146        lead to any editors to reload or any other editor manager actions. */
147     void filesChangedInternally(const Utils::FilePaths &filePaths);
148     /// emitted if all documents changed their name e.g. due to the file changing on disk
149     void allDocumentsRenamed(const Utils::FilePath &from, const Utils::FilePath &to);
150     /// emitted if one document changed its name e.g. due to save as
151     void documentRenamed(Core::IDocument *document,
152                          const Utils::FilePath &from,
153                          const Utils::FilePath &to);
154     void projectsDirectoryChanged(const Utils::FilePath &directory);
155 
156 private:
157     explicit DocumentManager(QObject *parent);
158     ~DocumentManager() override;
159 
160     void documentDestroyed(QObject *obj);
161     void checkForNewFileName();
162     void checkForReload();
163     void changedFile(const QString &file);
164     void filePathChanged(const Utils::FilePath &oldName, const Utils::FilePath &newName);
165     void updateSaveAll();
166     static void registerSaveAllAction();
167 
168     friend class Core::Internal::MainWindow;
169     friend class Core::Internal::DocumentManagerPrivate;
170 };
171 
172 class CORE_EXPORT FileChangeBlocker
173 {
174 public:
175     explicit FileChangeBlocker(const Utils::FilePath &filePath);
176     ~FileChangeBlocker();
177 private:
178     const Utils::FilePath m_filePath;
179     Q_DISABLE_COPY(FileChangeBlocker)
180 };
181 
182 } // namespace Core
183 
184 Q_DECLARE_METATYPE(Core::DocumentManager::RecentFile)
185