2
* This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3
* http://www.gnu.org/licenses/lgpl-3.0.html
6
#ifndef PROJECTMANAGER_H
7
#define PROJECTMANAGER_H
10
#include "globals.h" // DEFAULT_WORKSPACE
14
#include <wx/dynarray.h>
15
#include <wx/hashmap.h>
16
#include <wx/treectrl.h>
19
#include "cbexception.h"
28
class FilesGroupsAndMasks;
31
class wxFlatNotebookEvent;
33
DLLIMPORT extern int ID_ProjectManager; /* Used by both Project and Editor Managers */
34
WX_DEFINE_ARRAY(cbProject*, ProjectsArray);
35
WX_DECLARE_HASH_MAP(cbProject*, ProjectsArray*, wxPointerHash, wxPointerEqual, DepsMap); // for project dependencies
37
/** @brief The entry point singleton for working with projects.
39
* This is the project manager class. It handles all open projects and workspaces.
40
* It is through this class that you make requests about projects, like open
41
* a project, save it, set the active project (if more than one are opened), etc.
42
* To access a project, you must retrieve it from this class.
44
* As all managers, this is a singleton class which you retrieve by asking
45
* the global Manager singleton.
46
* E.g. Manager::Get()->GetProjectManager()
48
class DLLIMPORT ProjectManager : public Mgr<ProjectManager>, public wxEvtHandler
50
static bool s_CanShutdown;
52
friend class Mgr<ProjectManager>;
53
friend class Manager; // give Manager access to our private members
55
ProjectManager(const ProjectManager& rhs) { cbThrow(_T("Can't call ProjectManager's copy ctor!!!")); }
56
virtual void operator=(const ProjectManager& rhs){ cbThrow(_T("Can't assign an ProjectManager* !!!")); }
58
wxFlatNotebook* GetNotebook() { return m_pNotebook; }
60
// Can the app shutdown? (actually: is ProjectManager busy at the moment?)
61
static bool CanShutdown(){ return s_CanShutdown; }
62
/// Application menu creation. Called by the application only.
63
static void CreateMenu(wxMenuBar* menuBar);
64
/// Application menu removal. Called by the application only.
65
void ReleaseMenu(wxMenuBar* menuBar);
66
/** Retrieve the default path for new projects.
67
* @return The default path for new projects. Contains trailing path separator.
68
* @note This might be empty if not configured before...
70
wxString GetDefaultPath();
71
/** Set the default path for new projects.
72
* @note ProjectManager doesn't use this by itself. It's only doing the book-keeping.
73
* Usually this is set/queried from project wizards...*/
74
void SetDefaultPath(const wxString& path);
75
/** Is this a valid project? (i.e. is it still open?)
76
* @param project The project to check its validity.
77
* @return True if the project is valid (i.e. still open), false if not.
79
bool IsProjectStillOpen(cbProject* project);
80
/** Retrieve the active project. Most of the times, this is the function
81
* you 'll be calling in ProjectManager.
82
* @return A pointer to the active project.
84
cbProject* GetActiveProject(){ return m_pActiveProject; }
85
/** Retrieve an array of all the opened projects. This is a standard
86
* wxArray containing pointers to projects. Using this array you can
87
* iterate through all the opened projects.
88
* @return A pointer to the array containing the projects.
90
ProjectsArray* GetProjects(){ return m_pProjects; }
91
/** Check if a project is open based on the project's filename.
92
* @param filename The project's filename. Must be an absolute path.
93
* @return A pointer to the project if it is open, or NULL if it is not.
95
cbProject* IsOpen(const wxString& filename);
96
/** Set the active project. Use this function if you want to change the
98
* @param project A pointer to the new active project.
99
* @param refresh If true, refresh the project manager's tree, else do not refresh it.
101
void SetProject(cbProject* project, bool refresh = true);
102
/** Load a project from disk. This function, internally, uses IsOpen()
103
* so that the same project can't be loaded twice.
104
* @param filename The project file's filename.
105
* @param activateIt Active the project after loading.
106
* @return If the function succeeds, a pointer to the newly opened project
107
* is returned. Else the return value is NULL.
109
cbProject* LoadProject(const wxString& filename, bool activateIt = true);
110
/** Save a project to disk.
111
* @param project A pointer to the project to save.
112
* @return True if saving was succesful, false if not.
114
bool SaveProject(cbProject* project);
115
/** Save a project to disk, asking for a filename.
116
* @param project A pointer to the project to save.
117
* @return True if saving was succesful, false if not.
118
* @note A false return value doesn't necessarily mean failure. The user
119
* might have cancelled the SaveAs dialog...
121
bool SaveProjectAs(cbProject* project);
122
/** Save the active project to disk. Same as SaveProject(GetActiveProject()).
123
* @return True if saving was succesful, false if not.
125
bool SaveActiveProject();
126
/** Save the active project to disk, asking for a filename.
127
* Same as SaveProjectAs(GetActiveProject()).
128
* @return True if saving was succesful, false if not.
129
* @note A false return value doesn't necessarily mean failure. The user
130
* might have cancelled the SaveAs dialog...
132
bool SaveActiveProjectAs();
133
/** Saves all projects to disk.
134
* @return True if all projects were saved, false if even one save operation failed.
136
bool SaveAllProjects();
138
* @param project A pointer to the project to close.
139
* @param dontsave Force not (!) saving the project on close.
140
* @param refresh Force a refresh of the project tree after closing a project.
141
* @return True if project was closed, false if not.
143
bool CloseProject(cbProject* project, bool dontsave = false, bool refresh = true);
144
/** Close the active project. Same as CloseProject(GetActiveProject()).
145
* @return True if project was closed, false if not.
147
bool CloseActiveProject(bool dontsave = false);
148
/** Close all projects.
149
* @return True if all projects were closed, false if even one close operation failed.
151
bool CloseAllProjects(bool dontsave = false);
152
/** Checks whether all projects are saved. If not, asks
153
* the user to save and saves accordingly.
154
* @return False if the user pressed cancel.
155
* Note: calls QueryCloseProject for all projects.
157
bool QueryCloseAllProjects();
159
/** Checks whether project is saved. If not, asks
160
* the user to save and saves accordingly.
161
* @return False if the user pressed cancel.
162
* Note: By default this asks the user if he should
163
* save any unmodified files in the project.
165
bool QueryCloseProject(cbProject *proj,bool dontsavefiles=false);
167
/** Move a project up in the project manager tree. This effectively
168
* re-orders the projects build order.
169
* @param project The project to move up.
170
* @param warpAround If true and the project is at the top of the list order,
171
* then it wraps and goes to the bottom of the list.
173
void MoveProjectUp(cbProject* project, bool warpAround = false);
174
/** Move a project down in the project manager tree. This effectively
175
* re-orders the projects build order.
176
* @param project The project to move down.
177
* @param warpAround If true and the project is at the bottom of the list order,
178
* then it wraps and goes to the top of the list.
180
void MoveProjectDown(cbProject* project, bool warpAround = false);
181
/** Create a new empty project.
182
* @param filename the project's filename
183
* @return A pointer to the new project if succesful, or NULL if not.
184
* @note When the new project is created, if no filename parameter was supplied,
185
* it asks the user where to save it.
186
* If the user cancels the Save dialog, then NULL is returned from this function.
188
cbProject* NewProject(const wxString& filename = wxEmptyString);
189
/** Add a file to a project. This function comes in two versions. This version,
190
* expects a single build target index for the added file to belong to.
191
* @param filename The file to add to the project.
192
* @param project The project to add this file to. If NULL, the active project is used.
193
* @param target The index of the project's build target to add this file.
194
* @return The build target's index that this file was added to.
195
* @note If the target index supplied is -1 then, if the project has exactly
196
* one build target, the file is added to this single build target.
197
* If the project has more than one build targets, a dialog appears so
198
* that the user can select which build target this file should belong to.
200
int AddFileToProject(const wxString& filename, cbProject* project = 0L, int target = -1);
201
/** Add a file to a project. This function comes in two versions. This version,
202
* expects an array of build target indices for the added file to belong to.
203
* @param filename The file to add to the project.
204
* @param project The project to add this file to. If NULL, the active project is used.
205
* @param targets The array of the project's build targets indices to add this file.
206
* @return The number of build targets this file was added to.
207
* @note If the targets array is empty then, if the project has exactly
208
* one build target, the file is added to this single build target.
209
* If the project has more than one build targets, a dialog appears so
210
* that the user can select which build targets (multiple) this file should belong to.\n
211
* Also note than when this function returns, the targets array will contain
212
* the user-selected build targets.
214
int AddFileToProject(const wxString& filename, cbProject* project, wxArrayInt& targets);
215
/** Add multiple files to a project. This function comes in two versions. This version,
216
* expects a single build target index for the added files to belong to.
217
* @param filelist The files to add to the project.
218
* @param project The project to add these files to. If NULL, the active project is used.
219
* @param target The index of the project's build target to add these files.
220
* @return The build target's index that these files were added to.
221
* @note If the target index supplied is -1 then, if the project has exactly
222
* one build target, the files are added to this single build target.
223
* If the project has more than one build targets, a dialog appears so
224
* that the user can select which build target these files should belong to.
226
int AddMultipleFilesToProject(const wxArrayString& filelist, cbProject* project, int target = -1);
227
/** Add multiple files to a project. This function comes in two versions. This version,
228
* expects an array of build target indices for the added files to belong to.
229
* @param filelist The files to add to the project.
230
* @param project The project to add this file to. If NULL, the active project is used.
231
* @param targets The array of the project's build targets indices to add this file.
232
* @return The number of build targets these files were added to.
233
* @note If the targets array is empty then, if the project has exactly
234
* one build target, the files are added to this single build target.
235
* If the project has more than one build targets, a dialog appears so
236
* that the user can select which build targets (multiple) these files should belong to.\n
237
* Also note than when this function returns, the targets array will contain
238
* the user-selected build targets.
240
int AddMultipleFilesToProject(const wxArrayString& filelist, cbProject* project, wxArrayInt& targets);
241
/** Utility function. Displays a single selection list of a project's
242
* build targets to choose from.
243
* @param project The project to use. If NULL, the active project is used.
244
* @return The selected build target's index, or -1 if no build target was selected.
246
int AskForBuildTargetIndex(cbProject* project = 0L);
247
/** Utility function. Displays a multiple selection list of a project's
248
* build targets to choose from.
249
* @param project The project to use. If NULL, the active project is used.
250
* @return An integer array containing the selected build targets indices.
251
* This array will be empty if no build targets were selected.
253
wxArrayInt AskForMultiBuildTargetIndex(cbProject* project = 0L);
254
/** Load a workspace.
255
* @param filename The workspace to open.
256
* @return True if the workspace loads succefully, false if not.
258
bool LoadWorkspace(const wxString& filename = DEFAULT_WORKSPACE);
259
/** Save the open workspace.
260
* @return True if the workspace is saved succefully, false if not.
262
bool SaveWorkspace();
263
/** Save the open workspace under a different filename.
264
* @param filename The workspace to save.
265
* @return True if the workspace is saved succefully, false if not.
267
bool SaveWorkspaceAs(const wxString& filename);
268
/** Close the workspace.
269
* @return True if the workspace closes, false if not (the user is asked to save
270
* the workspace, if it is modified)
272
bool CloseWorkspace();
274
/** Check if the project manager is loading a project.
275
* @return True if it's loading a project, false otherwise
277
bool IsLoadingProject();
278
/** Check if the project manager is loading a workspace.
279
* @return True if it's loading a workspace, false otherwise
281
bool IsLoadingWorkspace();
282
/** Check if the project manager is loading a project/workspace.
283
* @return True if it's loading a project/workspace, false otherwise
286
/** Check if the project manager is closing a project.
287
* @return True if it's closing a project, false otherwise
289
bool IsClosingProject();
290
/** Check if the project manager is closing a workspace.
291
* @return True if it's closing a workspace, false otherwise
293
bool IsClosingWorkspace();
294
/** Check if the project manager is loading/closing a project/workspace.
295
* @return True if it is loading/closing something, false otherwise
297
bool IsLoadingOrClosing();
298
/** For use with plugins. Checks whether files in the project MAY be processed.
299
* This function has been made static for your convenience :)
300
* @return true if Loading,closing a project/workspace, or if the app is shutting down. False otherwise
302
static bool IsBusy();
303
/** Get the current workspace filename.
304
* @return The current workspace filename.
306
cbWorkspace* GetWorkspace();
309
/** @brief Adds a project as a dependency of another project.
310
* Projects inside workspaces allow you to set dependencies between them.
311
* When project A depends on project B, this means that before building
312
* project A, project B will be built because it obviously generates code
313
* that project A depends upon.
314
* @param base The project to set a dependency for.
315
* @param dependsOn the project that must be built before @c base project.
317
bool AddProjectDependency(cbProject* base, cbProject* dependsOn);
318
/** @brief Removes a project dependency.
319
* @see AddProjectDependency()
320
* @param base The project to remove a dependency from.
321
* @param doesNotDependOn The project that is to stop being a dependency of project @c base.
323
void RemoveProjectDependency(cbProject* base, cbProject* doesNotDependOn);
324
/** @brief Removes all dependencies from project @c base.
325
* @see AddProjectDependency()
326
* @param base The project to remove all dependencies from.
328
void ClearProjectDependencies(cbProject* base);
329
/** @brief Removes the project @c base from being a dependency of any other project.
330
* @see AddProjectDependency()
331
* @param base The project to remove from all dependencies.
333
void RemoveProjectFromAllDependencies(cbProject* base);
334
/** @brief Get the array of projects @c base depends on.
335
* @param base The project to get its dependencies.
336
* @return An array of project dependencies, or NULL if no dependencies are set for @c base.
338
const ProjectsArray* GetDependenciesForProject(cbProject* base);
339
/** Displays a dialog to setup project dependencies.
340
* @param base The project to setup its dependencies. Can be NULL (default) because there's a project selection combo in the dialog.
342
void ConfigureProjectDependencies(cbProject* base = 0);
343
/** Checks for circular dependencies between @c base and @c dependsOn.
344
* @return True if circular dependency is detected, false if it isn't.
346
bool CausesCircularDependency(cbProject* base, cbProject* dependsOn);
349
/// Rebuild the project manager's tree.
351
/** Stop the tree control from updating.
352
* @note This operation is accumulative. This means you have to call
353
* UnfreezeTree() as many times as you 've called FreezeTree() for the
354
* tree control to un-freeze (except if you call UnfreezeTree(true)).
357
/** Le the tree control be updated again.
358
* @param force If true the tree control is forced to un-freeze. Else it
359
* depends on freeze-unfreeze balance (see note).
360
* @note This operation is accumulative. This means you have to call
361
* UnfreezeTree() as many times as you 've called FreezeTree() for the
362
* tree control to un-freeze (except if you call UnfreezeTree(true)).
364
void UnfreezeTree(bool force = false);
365
/** Retrieve a pointer to the project manager's tree (GUI).
366
* @return A pointer to a wxTreeCtrl window.
368
wxTreeCtrl* GetTree(){ return m_pTree; }
369
/** Retrieve a pointer to the project manager's panel (GUI). This panel
370
* is the parent of the project manager's tree obtained through GetTree().
371
* @return A pointer to a wxPanel window.
373
wxMenu* GetProjectMenu();
374
/** Sets the Top Editor (the active editor from the last session) */
375
void SetTopEditor(EditorBase* ed);
376
/** @return The Top Editor */
377
EditorBase* GetTopEditor() const;
379
/** @return The workspace icon index in the image list.
380
@param read_only Return the read-only icon for a workspace?
382
int WorkspaceIconIndex(bool read_only = false);
383
/** @return The project icon index in the image list.
384
@param read_only Return the read-only icon for a project?
386
int ProjectIconIndex(bool read_only = false);
387
/** @return The folder icon index in the image list. */
388
int FolderIconIndex();
389
/** @return The virtual folder icon index in the image list. */
390
int VirtualFolderIconIndex();
392
/** Check if one of the open projects has been modified outside the IDE. If so, ask to reload it. */
393
void CheckForExternallyModifiedProjects();
395
/** Sends message to the plugins that the workspace has been changed */
396
void WorkspaceChanged();
398
/** Begins the project loading process. Only to be used by code that needs it (e.g. project importers).
399
* @return True on success, false on failure.
400
* @note This call *must* be "closed" by a call to EndLoadingProject()!
402
bool BeginLoadingProject();
404
/** Ends the project loading process. Only to be used by code that needs it (e.g. project importers).
405
* @param project The loaded project.
406
* @note A call to BeginLoadingProject() must have preceded.
408
void EndLoadingProject(cbProject* project);
410
/** Begins the workspace loading process. Only to be used by code that needs it (e.g. workspace importers).
411
* @return True on success, false on failure.
412
* @note This call *must* be "closed" by a call to EndLoadingWorkspace()!
414
bool BeginLoadingWorkspace();
416
/** Ends the workspace loading process. Only to be used by code that needs it (e.g. workspace importers).
417
* @note A call to BeginLoadingWorkspace() must have preceded.
419
void EndLoadingWorkspace();
424
/** Asks user to save the workspace, projects and files
425
* (Yes/No/cancel). If user pressed Yes, it saves accordingly.
426
* @return False if the user pressed cancel; true otherwise.
427
* After this function is called and returns true, it
428
* is safe to close the workspace, all files and projects
429
* without asking the user later.
431
bool QueryCloseWorkspace();
435
void ShowMenu(wxTreeItemId id, const wxPoint& pt);
436
void OnTabPosition(wxCommandEvent& event);
437
void OnProjectFileActivated(wxTreeEvent& event);
438
void OnExecParameters(wxCommandEvent& event);
439
void OnTreeItemRightClick(wxTreeEvent& event);
440
void OnTreeBeginDrag(wxTreeEvent& event);
441
void OnTreeEndDrag(wxTreeEvent& event);
442
void OnRightClick(wxCommandEvent& event);
443
void OnRenameWorkspace(wxCommandEvent& event);
444
void OnSaveWorkspace(wxCommandEvent& event);
445
void OnSaveAsWorkspace(wxCommandEvent& event);
446
void OnCloseWorkspace(wxCommandEvent& event);
447
void OnSetActiveProject(wxCommandEvent& event);
448
void OnAddFilesToProjectRecursively(wxCommandEvent& event);
449
void OnAddFileToProject(wxCommandEvent& event);
450
void OnRemoveFileFromProject(wxCommandEvent& event);
451
void OnRenameFile(wxCommandEvent& event);
452
void OnCloseProject(wxCommandEvent& event);
453
void OnCloseFile(wxCommandEvent& event);
454
void OnOpenFile(wxCommandEvent& event);
455
void OnOpenWith(wxCommandEvent& event);
456
void OnProperties(wxCommandEvent& event);
457
void OnNotes(wxCommandEvent& event);
458
void OnGotoFile(wxCommandEvent& event);
459
void OnViewCategorize(wxCommandEvent& event);
460
void OnViewUseFolders(wxCommandEvent& event);
461
void OnViewFileMasks(wxCommandEvent& event);
462
void OnFindFile(wxCommandEvent& event);
463
wxTreeItemId FindItem(wxTreeItemId Node, const wxString& Search) const;
464
void OnBeginEditNode(wxTreeEvent& event);
465
void OnEndEditNode(wxTreeEvent& event);
466
void OnAddVirtualFolder(wxCommandEvent& event);
467
void OnDeleteVirtualFolder(wxCommandEvent& event);
468
void OnUpdateUI(wxUpdateUIEvent& event);
469
void OnIdle(wxIdleEvent& event);
470
void OnAppDoneStartup(CodeBlocksEvent& event);
472
void DoOpenSelectedFile();
473
void DoOpenFile(ProjectFile* pf, const wxString& filename);
474
int DoAddFileToProject(const wxString& filename, cbProject* project, wxArrayInt& targets);
475
void RemoveFilesRecursively(wxTreeItemId& sel_id);
477
wxFlatNotebook* m_pNotebook;
479
wxTreeItemId m_TreeRoot;
480
cbProject* m_pActiveProject;
481
wxImageList* m_pImages;
482
ProjectsArray* m_pProjects;
483
DepsMap m_ProjectDeps;
484
cbWorkspace* m_pWorkspace;
485
bool m_TreeCategorize;
486
bool m_TreeUseFolders;
487
FilesGroupsAndMasks* m_pFileGroups;
488
int m_TreeFreezeCounter;
489
bool m_IsLoadingProject;
490
bool m_IsLoadingWorkspace;
491
bool m_IsClosingProject;
492
bool m_IsClosingWorkspace;
493
wxString m_InitialDir;
494
wxTreeItemId m_DraggingItem;
495
bool m_isCheckingForExternallyModifiedProjects;
496
bool m_CanSendWorkspaceChanged;
498
DECLARE_EVENT_TABLE()
501
#endif // PROJECTMANAGER_H