1 /*
2     SPDX-FileCopyrightText: 2006 Adam Treat <treat@kde.org>
3     SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef KDEVPLATFORM_PROJECTCONTROLLER_H
9 #define KDEVPLATFORM_PROJECTCONTROLLER_H
10 
11 #include <interfaces/iprojectcontroller.h>
12 
13 #include <QUrl>
14 
15 #include <KIO/UDSEntry>
16 
17 #include "shellexport.h"
18 
19 namespace Sublime {
20     class Area;
21 }
22 
23 namespace KIO {
24     class Job;
25 }
26 
27 namespace KDevelop
28 {
29 
30 class IProject;
31 class Core;
32 class Context;
33 class ContextMenuExtension;
34 class IPlugin;
35 class ProjectControllerPrivate;
36 
37 class KDEVPLATFORMSHELL_EXPORT IProjectDialogProvider : public QObject
38 {
39 Q_OBJECT
40 public:
41     IProjectDialogProvider();
42     ~IProjectDialogProvider() override;
43 
44 public Q_SLOTS:
45     /**
46      * Displays some UI to ask the user for the project location.
47      *
48      * @param fetch will tell the UI that the user might want to fetch the project first
49      * @param startUrl tells where to look first
50      */
51     virtual QUrl askProjectConfigLocation(bool fetch, const QUrl& startUrl = QUrl(),
52                                           const QUrl& repoUrl = QUrl(), IPlugin* plugin = nullptr) = 0;
53     virtual bool userWantsReopen() = 0;
54 };
55 
56 class KDEVPLATFORMSHELL_EXPORT ProjectController : public IProjectController
57 {
58     Q_OBJECT
59     Q_CLASSINFO( "D-Bus Interface", "org.kdevelop.ProjectController" )
60     friend class Core;
61     friend class CorePrivate;
62     friend class ProjectPreferences;
63 
64 public:
65     explicit ProjectController( Core* core );
66     ~ProjectController() override;
67 
68     IProject* projectAt( int ) const override;
69     int projectCount() const override;
70     QList<IProject*> projects() const override;
71 
72     ProjectBuildSetModel* buildSetModel() override;
73     ProjectModel* projectModel() override;
74     ProjectChangesModel* changesModel() override;
75     IProject* findProjectByName( const QString& name ) override;
76     IProject* findProjectForUrl( const QUrl& ) const override;
77 
78     bool isProjectNameUsed( const QString& name ) const override;
79     void setDialogProvider(IProjectDialogProvider*);
80 
81     QUrl projectsBaseDirectory() const override;
82     QString prettyFileName(const QUrl& url, FormattingOptions format = FormatHtml) const override;
83     QString prettyFilePath(const QUrl& url, FormattingOptions format = FormatHtml) const override;
84 
85     ContextMenuExtension contextMenuExtension(KDevelop::Context* ctx, QWidget* parent);
86 
87     enum FetchFlag {
88         NoFetchFlags = 0,
89         FetchShowErrorIfNotSupported = 1,
90     };
91     Q_DECLARE_FLAGS(FetchFlags, FetchFlag)
92 
93     /**
94      * @param repoUrl url identifying the repo
95      * @returns @c true if a plugin was found to handle the repo (also if user cancelled), @c false otherwise
96      */
97     bool fetchProjectFromUrl(const QUrl& repoUrl, FetchFlags fetchFlags = FetchShowErrorIfNotSupported);
98 
99 public Q_SLOTS:
openProjectForUrl(const QString & sourceUrl)100     Q_SCRIPTABLE void openProjectForUrl( const QString &sourceUrl ) { openProjectForUrl(QUrl(sourceUrl)); }
101     void openProjectForUrl( const QUrl &sourceUrl ) override;
102     void fetchProject();
103     void openProject( const QUrl &KDev4ProjectFile = QUrl() ) override;
104     void abortOpeningProject( IProject* );
105     void projectImportingFinished( IProject* );
106     void closeProject( IProject* ) override;
107     void closeAllProjects() override;
108     void configureProject( IProject* ) override;
109 
110     void reparseProject( IProject* project, bool forceUpdate = false, bool forceAll = false  ) override;
111 
112     void eventuallyOpenProjectFile(KIO::Job* job, const KIO::UDSEntryList& entries);
113     void openProjectForUrlSlot(bool);
114 //     void changeCurrentProject( ProjectBaseItem* );
115     void openProjects(const QList<QUrl>& projects);
116     void commitCurrentProject();
117 
118     // Maps the given path from the source to the equivalent path within the build directory
119     // of the corresponding project. If the path is already in the build directory and fallbackRoot is true,
120     // then it is mapped to the root of the build directory.
121     // This is used through DBus from within kdevplatform_shell_environment.sh
122     // If reverse is true, maps the opposite direction, from build to source. [ Used in kdevplatform_shell_environment.sh ]
123     Q_SCRIPTABLE QString mapSourceBuild( const QString& path, bool reverse = false, bool fallbackRoot = true ) const;
124 
125 protected:
126     /**
127      * Add the existing project @p project to the controller
128      *
129      * @note Method is used for testing objectives, consider using openProject() instead!
130      * @note takes ownership over the project
131      *
132      * @sa openProject()
133      */
134     void addProject(IProject* proj);
135     /**
136      * Remove the project @p project from the controller
137      *
138      * @note Ownership is passed on to the caller
139      */
140     void takeProject(IProject* proj);
141 
142     virtual void loadSettings( bool projectIsLoaded );
143     virtual void saveSettings( bool projectIsLoaded );
144 
145     virtual void initialize();
146 
147 Q_SIGNALS:
148     void initialized();
149 
150 private:
151     //FIXME Do not load all of this just for the project being opened...
152     //void legacyLoading();
153     void setupActions();
154     void cleanup();
155 
156     void saveRecentProjectsActionEntries();
157 
158     // helper methods for closeProject()
159     void unloadUnusedProjectPlugins(IProject* proj);
160     void disableProjectCloseAction();
161     void closeAllOpenedFiles(IProject* proj);
162     void initializePluginCleanup(IProject* proj);
163 
164 private:
165     const QScopedPointer<class ProjectControllerPrivate> d_ptr;
166     Q_DECLARE_PRIVATE(ProjectController)
167     friend class ProjectControllerPrivate;
168 };
169 
170 class ProjectDialogProvider : public IProjectDialogProvider
171 {
172 Q_OBJECT
173 public:
174     explicit ProjectDialogProvider(ProjectControllerPrivate* p);
175     ~ProjectDialogProvider() override;
176     ProjectControllerPrivate* const d;
177 
178 public Q_SLOTS:
179     QUrl askProjectConfigLocation(bool fetch, const QUrl& startUrl,
180                                   const QUrl& repoUrl, IPlugin* plugin) override;
181     bool userWantsReopen() override;
182 };
183 
184 
185 }
186 #endif
187