Code::Blocks  SVN r11506
cbproject.cpp
Go to the documentation of this file.
1 /*
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
4  *
5  * $Revision: 11471 $
6  * $Id: cbproject.cpp 11471 2018-09-17 21:16:06Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/sdk/cbproject.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 
12 #ifndef wxUSE_CHOICEDLG
13  #define wxUSE_CHOICEDLG 1
14 #endif
15 
16 #include <wx/choicdlg.h>
17 #include <wx/filedlg.h>
18 #include <wx/filename.h>
19 
20 #ifndef CB_PRECOMP
21  #include <wx/dir.h>
22 
23  #include "cbproject.h" // class's header file
24  #include "cbeditor.h"
25  #include "cbtreectrl.h"
26  #include "compiler.h" // GetSwitches
27  #include "compilerfactory.h"
28  #include "configmanager.h"
29  #include "editormanager.h"
30  #include "filemanager.h"
31  #include "globals.h"
32  #include "infowindow.h"
33  #include "logmanager.h"
34  #include "macrosmanager.h"
35  #include "manager.h"
36  #include "pluginmanager.h"
37  #include "projectbuildtarget.h"
38  #include "projectfile.h"
39  #include "projectmanager.h"
40  #include "sdk_events.h"
41 #endif
42 
43 #include <map>
44 #include "projectloader.h"
45 #include "projectlayoutloader.h"
46 #include "selecttargetdlg.h"
47 #include "filegroupsandmasks.h"
48 #include "filefilters.h"
49 #include "annoyingdialog.h"
52 #include "cbcolourmanager.h"
53 
54 // class constructor
55 cbProject::cbProject(const wxString& filename) :
56  m_CustomMakefile(false),
57  m_Globs(),
58  m_FileArray(ProjectFile::CompareProjectFiles),
59  m_Loaded(false),
60  m_CurrentlyLoading(false),
61  m_PCHMode(pchSourceFile),
62  m_CurrentlyCompilingTarget(nullptr),
63  m_ExtendedObjectNamesGeneration(false),
64  m_AutoShowNotesOnLoad(false),
65  m_CheckForExternallyModifiedFiles(true),
66  m_pExtensionsElement(nullptr)
67 {
69  SetModified(false);
70 
71  wxString realFile = realpath(filename);
72 
73  m_Files.clear();
74  m_FileArray.Clear();
75  if (!realFile.IsEmpty() && (wxFileExists(realFile) || wxDirExists(realFile)))
76  {
77  // existing project
78  m_Filename = realFile;
80  Open();
81  }
82  else
83  {
84  // new project
85  SetModified(true);
86  if (realFile.IsEmpty())
87  {
89  m_Loaded = SaveAs();
90  }
91  else
92  {
93  m_Filename = realFile;
94  m_Loaded = Save();
95  }
96  if (m_Loaded)
97  {
98  wxFileName fname(m_Filename);
99  m_Title = fname.GetName();
102 
103  // moved to ProjectManager::LoadProject()
104  // see explanation there...
105 // NotifyPlugins(cbEVT_PROJECT_OPEN);
106  }
107  }
108 }
109 
110 // class destructor
112 {
113  // moved to ProjectManager::CloseProject()
114  // see explanation there...
115 // NotifyPlugins(cbEVT_PROJECT_CLOSE);
116 
118 }
119 
120 void cbProject::NotifyPlugins(wxEventType type, const wxString& targetName, const wxString& oldTargetName)
121 {
122  CodeBlocksEvent event(type);
123  event.SetProject(this);
124  event.SetBuildTargetName(targetName);
125  event.SetOldBuildTargetName(oldTargetName);
126  Manager::Get()->ProcessEvent(event);
127 }
128 
130 {
131 // TODO (mandrav##): Is this needed? The project's compiler has nothing to do with the targets' compilers...
132 
134  if (id != GetCompilerID())
135  {
136  // update object filenames
137  for (unsigned int i = 0; i < m_Targets.GetCount(); ++i)
138  {
139  ProjectBuildTarget* target = m_Targets[i];
140  if (target)
141  {
142  Compiler* compiler = CompilerFactory::GetCompiler(target->GetCompilerID());
143  if (!compiler)
144  continue;
145 
146  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
147  {
148  ProjectFile* pf = *it;
149  wxFileName obj(pf->GetObjName());
150  if ( (FileTypeOf(pf->relativeFilename) != ftResource)
151  && (obj.GetExt() == compiler->GetSwitches().objectExtension) )
152  {
153  obj.SetExt(compiler->GetSwitches().objectExtension);
154  pf->SetObjName(obj.GetFullName());
155  }
156  }
157  }
158  }
159  }
160 }
161 
163 {
164  // check base options
166  return true;
167 
168  // check targets
169  for (unsigned int i = 0; i < m_Targets.GetCount(); ++i)
170  {
171  ProjectBuildTarget* target = m_Targets[i];
172  if (target->GetModified())
173  return true;
174  }
175 
176  return false;
177 }
178 
179 void cbProject::SetModified(bool modified)
180 {
182 
183  // modify targets
184  for (unsigned int i = 0; i < m_Targets.GetCount(); ++i)
185  {
186  ProjectBuildTarget* target = m_Targets[i];
187  target->SetModified(modified);
188  }
189 
190  if (!modified)
192 }
193 
195 {
196  if (m_CustomMakefile != custom)
197  {
198  m_CustomMakefile = custom;
199  SetModified(true);
200  }
201 }
202 
204 {
205  const wxString prefix = _("Untitled");
206  wxString tmp;
207  ProjectsArray* arr = Manager::Get()->GetProjectManager()->GetProjects();
208  int projCount = arr->GetCount();
209  int iter = 1;
210  bool ok = false;
211  tmp << prefix << wxString::Format(_T("%d"), iter);
212  while (!ok)
213  {
214  tmp.Clear();
215  tmp << prefix << wxString::Format(_T("%d"), iter);
216 
217  ok = true;
218  for (int i = 0; i < projCount; ++i)
219  {
220  cbProject* prj = arr->Item(i);
221  wxFileName fname(prj->GetFilename());
222 
223  if (fname.GetName().Matches(tmp))
224  {
225  ok = false;
226  break;
227  }
228  }
229  if (ok)
230  break;
231  ++iter;
232  }
233  return tmp << _T(".") << FileFilters::CODEBLOCKS_EXT;
234 }
235 
237 {
238  // The macro manager stores pointers to projects and targets, so we need to clear it to prevent
239  // dangling pointer bugs.
241 
243 
244  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end();++it)
245  delete(*it);
246  m_Files.clear();
247  m_FileArray.Clear();
251  m_LibDirs.Clear();
252 
253  while (m_Targets.GetCount())
254  {
255  ProjectBuildTarget* target = m_Targets[0];
256  delete target;
257  m_Targets.RemoveAt(0);
258  }
259  SetModified(true);
260 
262 }
263 
265 {
266  m_Loaded = false;
267  m_ProjectFilesMap.clear();
269 
271  {
272  wxString msg;
273  msg.Printf(_("Project '%s' does not exist..."), m_Filename.c_str());
274  cbMessageBox(msg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
275  return;
276  }
277 
278  bool fileUpgraded = false;
279  bool fileModified = false;
280  wxFileName fname(m_Filename);
282  if (ft == ftCodeBlocksProject)
283  {
284  Manager::Get()->GetLogManager()->Log(_("Opening ") + m_Filename);
285  m_CurrentlyLoading = true;
286  ProjectLoader loader(this);
288  fileUpgraded = loader.FileUpgraded();
289  fileModified = loader.FileModified();
290  m_CurrentlyLoading = false;
291 
292  if (m_Loaded)
293  {
295  Manager::Get()->GetLogManager()->Log(_("Done."));
296  if (!m_Targets.GetCount())
298  // in case of batch build discard upgrade messages
299  fileUpgraded = fileUpgraded && !Manager::IsBatchBuild();
300  SetModified(ft != ftCodeBlocksProject || fileUpgraded || fileModified);
301 
302  // moved to ProjectManager::LoadProject()
303  // see explanation there...
304  // NotifyPlugins(cbEVT_PROJECT_OPEN);
305 
306  if (fileUpgraded)
307  {
309  _("The loaded project file was generated\n"
310  "with an older version of Code::Blocks.\n\n"
311  "Code::Blocks can import older project files,\n"
312  "but will always save in the current format."), 12000, 2000);
313  }
315  }
316  }
317 } // end of Open
318 
320 {
321  // find the common toplevel path
322  // for simple projects, this might be the path to the project file
323  // for projects where the project file is in a subdir, files will
324  // have ".." in their paths
326  wxFileName base = GetBasePath() + sep;
327  wxString vol = base.GetVolume();
328  bool prjHasUNCName = base.GetFullPath().StartsWith(_T("\\\\"));
329 
330  Manager::Get()->GetLogManager()->DebugLog(_T("Project's base path: ") + base.GetFullPath());
331 
332  // This loop takes ~30ms for 1000 project files
333  // it's as fast as it can get, considered that it used to take ~1200ms ;)
334  // don't even bother making it faster - you can't :)
335 #ifdef ctlp_measuring
336  wxStopWatch sw;
337 #endif
338  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
339  {
340  ProjectFile* f = (*it);
341  if (!f)
342  continue;
343 
344  if ( !vol.IsSameAs(f->file.GetVolume()) )
345  continue;
346 
347  bool fileHasUNCName = f->file.GetFullPath().StartsWith(_T("\\\\"));
348 
349  if ( (!prjHasUNCName && fileHasUNCName)
350  || ( prjHasUNCName && !fileHasUNCName) )
351  {
352  continue;
353  }
354 
355  wxString tmp = f->relativeFilename;
356  wxString tmpbase = m_BasePath;
357 
358  size_t pos = 0;
359  while ( (pos < tmp.Length())
360  && ( (tmp.GetChar(pos) == _T('.'))
361  || (tmp.GetChar(pos) == _T('/'))
362  || (tmp.GetChar(pos) == _T('\\')) ) )
363  {
364  ++pos;
365  }
366  if ( (pos > 0) && (pos < tmp.Length()) )
367  tmpbase << sep << tmp.Left(pos) << sep;
368 
369  wxFileName tmpbaseF(tmpbase); tmpbaseF.Normalize(wxPATH_NORM_DOTS);
370  if ( (tmpbaseF.GetDirCount() < base.GetDirCount())
371  && (base.GetPath().StartsWith(tmpbaseF.GetPath())) )
372  {
373  base = tmpbaseF;
374  }
375  }
376 #ifdef ctlp_measuring
377  Manager::Get()->GetLogManager()->DebugLogError(F(_T("%s::%s:%d took : %d ms"), cbC2U(__FILE__).c_str(),cbC2U(__PRETTY_FUNCTION__).c_str(), __LINE__, (int)sw.Time()));
378 #endif
379 
381  Manager::Get()->GetLogManager()->DebugLog(_T("Project's common toplevel path: ") + m_CommonTopLevelPath);
382 
383  const wxString &projectBasePath = GetBasePath();
384 
385  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
386  {
387  ProjectFile* f = (*it);
388  if (!f)
389  continue;
390 
391  wxString fileName = f->file.GetFullPath();
392  bool fileHasUNCName = fileName.StartsWith(_T("\\\\"));
393 
394  if ( (prjHasUNCName && fileHasUNCName)
395  || ( !prjHasUNCName
396  && !fileHasUNCName
397  && vol.IsSameAs(f->file.GetVolume()) ) )
398  {
399  wxFileName relFileCTLP(f->file);
400  relFileCTLP.MakeRelativeTo( m_CommonTopLevelPath );
401  wxFileName relFileBase(f->file);
402  relFileBase.MakeRelativeTo(projectBasePath);
403 
404  // The commented (old) method to obtain the relativeToCommonTopLevelPath is fast, but does *not* work, if you save
405  // the project on a different drive in a sub-folder of an existing source file on that (different) drive:
406  // I.e.: Project on C:\Folder\Project.cbp has file C:\Folder\SubFolder\foo.cpp and D:\Folder\bar.cpp
407  // Saved the project under D:\Folder\SubFolder\ProjectNew.cbp would cause a wrong computation of bar.cpp otherwise!!!
408 // f->relativeToCommonTopLevelPath = fileName.Right(fileName.Length() - m_CommonTopLevelPath.Length());
409  // Using wxFileName instead, although its costly:
410  f->relativeToCommonTopLevelPath = relFileCTLP.GetFullPath();
411  f->relativeFilename = relFileBase.GetFullPath();
412  }
413  else
414  {
415  f->relativeToCommonTopLevelPath = fileName;
416  f->relativeFilename = fileName;
417  }
418 
420  }
421 }
422 
424 {
425  return m_CommonTopLevelPath;
426 }
427 
429 {
431 }
432 
434 {
435  wxFileName fname;
436  fname.Assign(m_Filename);
437  wxFileDialog dlg(Manager::Get()->GetAppWindow(),
438  _("Save file"),
439  fname.GetPath(),
440  fname.GetFullName(),
443 
444  PlaceWindow(&dlg);
445  if (dlg.ShowModal() != wxID_OK)
446  return false;
447 
448  wxFileName newName(dlg.GetPath());
449 
450  // if the filename has changed, we need to recalculate the common toplevel path
451  bool pathChanged = !newName.GetPath().IsSameAs(fname.GetPath());
452 
453  m_Filename = newName.GetFullPath();
454  fname.Assign(m_Filename);
455 
456  // make sure the project file uses the correct extension
457  // we don't use wxFileName::SetExt() because if the user has added a dot
458  // in the filename, the part after it would be interpreted as extension
459  // (and it might not be)
460  // so we just append the correct extension
463 
464 // Manager::Get()->GetProjectManager()->GetTree()->SetItemText(m_ProjectNode, fname.GetFullName());
465  if (!m_Loaded)
467  if (pathChanged)
469  ProjectLoader loader(this);
470  if (loader.Save(m_Filename, m_pExtensionsElement))
471  {
472  fname = m_Filename;
475  return true;
476  }
477 
478  cbMessageBox(_("Couldn't save project ") + m_Filename + _("\n(Maybe the file is write-protected?)"), _("Warning"), wxICON_WARNING);
479  return false;
480 }
481 
483 {
484  if (m_Filename.IsEmpty())
485  return SaveAs();
486  ProjectLoader loader(this);
487  if (loader.Save(m_Filename, m_pExtensionsElement))
488  {
489  wxFileName fname(m_Filename);
492  return true;
493  }
494 
495  cbMessageBox(_("Couldn't save project ") + m_Filename + _("\n(Maybe the file is write-protected?)"), _("Warning"), wxICON_WARNING);
496  return false;
497 }
498 
500 {
501  if (m_Filename.IsEmpty())
502  return false;
503 
504  if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/enable_project_layout"), true) == false)
505  return true;
506 
507  wxFileName fname(m_Filename);
508  fname.SetExt(_T("layout"));
509  ProjectLayoutLoader loader(this);
510  return loader.Save(fname.GetFullPath());
511 }
512 
514 {
515  if (m_Filename.IsEmpty())
516  return false;
517 
518  if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/enable_project_layout"), true) == false)
519  return true;
520 
521  int openmode = Manager::Get()->GetConfigManager(_T("project_manager"))->ReadInt(_T("/open_files"), (long int)1);
522  if (openmode==2)
523  return true; // Do not open any files
524 
526 
527  bool result = false;
528  if (openmode == 0) // Open all files
529  {
530  FilesList::iterator it = m_Files.begin();
531  while (it != m_Files.end())
532  {
533  ProjectFile* f = *it++;
535  }
536  result = true;
537  }
538  else if (openmode == 1)// Open last open files
539  {
540  wxFileName fname(m_Filename);
541  fname.SetExt(_T("layout"));
542  ProjectLayoutLoader loader(this);
543  if (loader.Open(fname.GetFullPath()))
544  {
545  typedef std::map<int, ProjectFile*> open_files_map;
546  open_files_map open_files;
547 
548  // Get all files to open and sort them according to their tab-position:
549  FilesList::iterator it = m_Files.begin();
550  while (it != m_Files.end())
551  {
552  ProjectFile* f = *it++;
553  // do not try to open files that do not exist, but have fileOpen set to true
554  if (f->editorOpen && wxFileExists(f->file.GetFullPath()))
555  open_files[f->editorTabPos] = f;
556  else
557  f->editorOpen = false;
558  }
559 
560  // Load all requested files
561  std::vector<LoaderBase*> filesInMemory;
562  for (open_files_map::iterator ofm_it = open_files.begin(); ofm_it != open_files.end(); ++ofm_it)
563  filesInMemory.push_back(Manager::Get()->GetFileManager()->Load((*ofm_it).second->file.GetFullPath()));
564 
565  // Open all requested files:
566  size_t i = 0;
567  for (open_files_map::iterator ofm_it = open_files.begin(); ofm_it != open_files.end(); ++ofm_it)
568  {
569  cbEditor* ed = Manager::Get()->GetEditorManager()->Open(filesInMemory[i], (*ofm_it).second->file.GetFullPath(),0,(*ofm_it).second);
570  if (ed)
571  ed->SetProjectFile((*ofm_it).second);
572  ++i;
573  }
574 
575  ProjectFile* f = loader.GetTopProjectFile();
576  if (f)
577  {
578  Manager::Get()->GetLogManager()->DebugLog(_T("Top Editor: ") + f->file.GetFullPath());
580  if (eb)
581  eb->Activate();
582  }
583  loader.LoadNotebookLayout();
584  }
585  result = true;
586  }
587 
589 
590  return result;
591 }
592 
594 {
596  event.SetProject(this);
597  Manager::Get()->ProcessEvent(event);
598 }
599 
601 {
603  event.SetProject(this);
604  Manager::Get()->ProcessEvent(event);
605 }
606 
608 {
610  event.SetProject(this);
611  Manager::Get()->ProcessEvent(event);
612 }
613 
615 {
617  event.SetProject(this);
618  Manager::Get()->ProcessEvent(event);
619 }
620 
621 ProjectFile* cbProject::AddFile(const wxString& targetName, const wxString& filename, bool compile, bool link, unsigned short int weight)
622 {
623  int idx = IndexOfBuildTargetName(targetName);
624  return AddFile(idx, filename, compile, link, weight);
625 }
626 
627 ProjectFile* cbProject::AddFile(int targetIndex, const wxString& filename, bool compile, bool link, cb_unused unsigned short int weight)
628 {
629 // NOTE (Rick#1#): When loading the project, do not search for existing files
630 // (Assuming that there are no duplicate entries in the .cbp file)
631 // This saves us a lot of processing when loading large projects.
632 // Remove the if to do the search anyway
633 
634 // NOTE (mandrav#1#): We can't ignore that because even if we can rely on .cbp
635 // containing discrete files, we can't do that for imported projects...
636 // This means we have to search anyway.
637 // NP though, I added a hashmap for fast searches in GetFileByFilename()
638 
639 /* NOTE (mandrav#1#): Calling GetFileByFilename() twice, is costly.
640  Instead of searching for duplicate files when entering here,
641  we 'll search before exiting.
642  The rationale is that by then, we 'll have the relative filename
643  in our own representation and this will make everything quicker
644  (check GetFileByFilename implementation to understand why)...
645 */
646 // f = GetFileByFilename(filename, true, true);
647 // if (!f)
648 // f = GetFileByFilename(filename, false, true);
649 // if (f)
650 // {
651 // if (targetIndex >= 0 && targetIndex < (int)m_Targets.GetCount())
652 // f->AddBuildTarget(m_Targets[targetIndex]->GetTitle());
653 // return f;
654 // }
655 
656  // quick test
657  ProjectFile* pf = m_ProjectFilesMap[UnixFilename(filename)];
658  if (pf)
659  return pf;
660 
661  // create file
662  pf = new ProjectFile(this);
663  bool localCompile, localLink;
664  wxFileName fname(filename);
665 
666  const wxString &ext = fname.GetExt();
667  if (ext.IsSameAs(FileFilters::C_EXT, false))
668  pf->compilerVar = _T("CC");
669  else if (platform::windows && ext.IsSameAs(FileFilters::RESOURCE_EXT))
670  pf->compilerVar = _T("WINDRES");
671  else
672  pf->compilerVar = _T("CPP"); // default
673 
674  if (!m_Targets.GetCount())
675  {
676  // no targets in project; add default
678  if (!m_Targets.GetCount())
679  {
680  delete pf;
681  return nullptr; // if that failed, fail addition of file...
682  }
683  }
684 
685  const FileType ft = FileTypeOf(filename);
686  const bool isResource = (ft == ftResource);
687 
688 // NOTE (mandrav#1#): targetIndex == -1 means "don't add file to any targets"
689 // This case gives us problems though because then we don't know the compiler
690 // this file will be using (per-target) which means we can't decide if it
691 // generates any files...
692 // We solve this issue with a hack (only for the targetIndex == -1 case!):
693 // We iterate all available target compilers tool and use generatedFiles from
694 // all of them. It works and is also safe.
695  std::map<Compiler*, const CompilerTool*> GenFilesHackMap;
696  if (targetIndex < 0 || targetIndex >= (int)m_Targets.GetCount())
697  {
699  if (c)
700  {
701  const CompilerTool* t = c->GetCompilerTool(isResource ? ctCompileResourceCmd : ctCompileObjectCmd, fname.GetExt());
702  if (t && t->generatedFiles.GetCount())
703  GenFilesHackMap[c] = t;
704  }
705 
706  for (unsigned int i = 0; i < m_Targets.GetCount(); ++i)
707  {
709  if (GenFilesHackMap.find(c) != GenFilesHackMap.end())
710  continue; // compiler already in map
711 
712  if (c)
713  {
714  const CompilerTool* t = c->GetCompilerTool(isResource ? ctCompileResourceCmd : ctCompileObjectCmd, fname.GetExt());
715  if (t && t->generatedFiles.GetCount())
716  GenFilesHackMap[c] = t;
717  }
718  }
719  }
720  else
721  {
722  // targetIndex is valid: just add a single entry to the map
724  if (c)
725  {
726  const CompilerTool* t = c->GetCompilerTool(isResource ? ctCompileResourceCmd : ctCompileObjectCmd, fname.GetExt());
727  if (t && t->generatedFiles.GetCount())
728  GenFilesHackMap[c] = t;
729  }
730  }
731 
732  // so... now, if GenFilesHackMap is not empty, we know
733  // 1) this file generates other files and
734  // 2) iterating the map will give us the generated file names :)
735 
736  // add the build target
737  if (targetIndex >= 0 && targetIndex < (int)m_Targets.GetCount())
738  pf->AddBuildTarget(m_Targets[targetIndex]->GetTitle());
739 
740  localCompile = compile
741  && ( ft == ftSource
742  || ft == ftResource
743  || !GenFilesHackMap.empty() );
744  localLink = link
745  && ( ft == ftSource
746  || ft == ftResource
747  || ft == ftObject
748  || ft == ftResourceBin
749  || ft == ftStaticLib );
750 
751  pf->compile = localCompile;
752  pf->link = localLink;
753 
754  wxString local_filename = filename;
755  const wxString &projectBasePath = GetBasePath();
756 
757 #ifdef __WXMSW__
758  // for Windows, make sure the filename is not on another drive...
759  if ( (local_filename.Length() > 1)
760  && (local_filename.GetChar(1) == _T(':'))
761  && (fname.GetVolume() != wxFileName(m_Filename).GetVolume()) )
762  // (this is a quick test to avoid the costly wxFileName ctor below)
763  {
764  fname.Assign(filename);
765  }
766  else if (fname.GetFullPath().StartsWith(_T("\\\\"))) // UNC path
767  {
768  fname.Assign(filename);
769  }
770  else
771 #endif
772  {
773  // make sure the filename is relative to the project's base path
774  if (fname.IsAbsolute())
775  {
776  fname.MakeRelativeTo(projectBasePath);
777  local_filename = fname.GetFullPath();
778  }
779  // this call is costly (wxFileName ctor):
780  fname.Assign(projectBasePath + wxFILE_SEP_PATH + local_filename);
781  }
782  fname.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_TILDE, projectBasePath);
783 
784  const wxString &fullFilename = realpath(fname.GetFullPath());
785  pf->file = fullFilename;
786  pf->relativeFilename = UnixFilename(local_filename);
787 
788  // now check if we have already added this file
789  // if we have, return the existing file, but add the specified target
790  ProjectFile* existing = GetFileByFilename(pf->relativeFilename, true, true);
791  if (existing == pf)
792  {
793  delete pf;
794  if (targetIndex >= 0 && targetIndex < (int)m_Targets.GetCount())
795  existing->AddBuildTarget(m_Targets[targetIndex]->GetTitle());
796  return existing;
797  }
798 
799  m_Files.insert(pf);
800  if (!m_CurrentlyLoading)
801  {
802  // Only add the file, if we are not currently loading the project and
803  // m_FileArray is already initialised.
804  // Initialising is done in the getter-function (GetFile(index), to save time,
805  // because in many cases m_FileArray is not needed
806  if ( m_FileArray.GetCount() > 0 )
807  m_FileArray.Add(pf);
808  // check if we really need to recalculate the common top-level path for the project
809  if ( !fullFilename.StartsWith(m_CommonTopLevelPath) )
811  else
812  {
813  // set f->relativeToCommonTopLevelPath
814  pf->relativeToCommonTopLevelPath = fullFilename.Right(fullFilename.Length() - m_CommonTopLevelPath.Length());
815  }
816  }
817  SetModified(true);
818  m_ProjectFilesMap[pf->relativeFilename] = pf; // add to hashmap
819 
820  if (!wxFileExists(fullFilename))
822  else if (!wxFile::Access(fullFilename.c_str(), wxFile::write)) // readonly
824 
825  if ( !GenFilesHackMap.empty() )
826  {
827  // auto-generated files!
828  wxFileName tmp = pf->file;
829  for (std::map<Compiler*, const CompilerTool*>::const_iterator it = GenFilesHackMap.begin(); it != GenFilesHackMap.end(); ++it)
830  {
831  const CompilerTool* tool = it->second;
832  for (size_t i = 0; i < tool->generatedFiles.GetCount(); ++i)
833  {
834  tmp.SetFullName(tool->generatedFiles[i]);
835  wxString tmps = tmp.GetFullPath();
836  // any macro replacements here, should also be done in
837  // CompilerCommandGenerator::GenerateCommandLine !!!
838  tmps.Replace(_T("$file_basename"), pf->file.GetName()); // old way - remove later
839  tmps.Replace(_T("$file_name"), pf->file.GetName());
840  tmps.Replace(_T("$file_dir"), pf->file.GetPath());
841  tmps.Replace(_T("$file_ext"), pf->file.GetExt());
842  tmps.Replace(_T("$file"), pf->file.GetFullName());
844 
845  ProjectFile* pfile = AddFile(targetIndex, UnixFilename(tmps));
846  if (!pfile)
847  Manager::Get()->GetLogManager()->DebugLog(_T("Can't add auto-generated file ") + tmps);
848  else
849  {
850  pf->generatedFiles.push_back(pfile);
851  pfile->SetAutoGeneratedBy(pf);
852  }
853  }
854  }
855  }
856 
857  return pf;
858 }
859 
861 {
862  if (!pf)
863  return false;
864  m_ProjectFilesMap.erase(UnixFilename(pf->relativeFilename)); // remove from hashmap
866 
867  {
868  FilesList::iterator it = m_Files.find(pf);
869 
870  if (it == m_Files.end())
871  {
872  Manager::Get()->GetLogManager()->DebugLog(_T("Can't locate node for ProjectFile* !"));
873  }
874  else
875  {
876  if (!m_FileArray.IsEmpty())
877  m_FileArray.Remove(*it);
878 
879  m_Files.erase(it);
880  }
881  }
882  // remove this file from all targets too
883  for (unsigned int i = 0; i < m_Targets.GetCount(); ++i)
884  {
885  if (ProjectBuildTarget* target = m_Targets[i])
886  target->RemoveFile(pf);
887  }
888 
889  // if this is auto-generated, inform "parent"
890  if (pf->AutoGeneratedBy())
891  {
892  ProjectFilesVector::iterator it = std::find(pf->AutoGeneratedBy()->generatedFiles.begin(),
893  pf->AutoGeneratedBy()->generatedFiles.end(), pf);
894  pf->AutoGeneratedBy()->generatedFiles.erase(it);
895  }
896 
897  // also remove generated files (see above code: files will empty the vector)
898  while (pf->generatedFiles.size())
899  RemoveFile(pf->generatedFiles[0]);
900  pf->generatedFiles.clear();
901 
902  delete pf;
903 
904  SetModified(true);
905  return true;
906 }
907 
909 {
910  return m_VirtualFolders;
911 }
912 
914 {
915  if (m_VirtualFolders.Index(folder)==wxNOT_FOUND)
916  {
917  m_VirtualFolders.push_back(folder);
918  return true;
919  }
920  else
921  return false;
922 }
923 
925 {
926  for (int i = (int)m_VirtualFolders.GetCount() - 1; i >= 0; --i)
927  {
928  if (m_VirtualFolders[i].StartsWith(folder))
930  }
931  // now loop all project files and remove them from this virtual folder
932  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
933  {
934  ProjectFile* f = *it;
935  if (f && !f->virtual_path.IsEmpty())
936  {
937  if (f->virtual_path.StartsWith(folder)) // need 2 checks because of last separator
938  f->virtual_path.Clear();
939  }
940  }
941 
942  SetModified(true);
943 }
944 
945 void cbProject::ReplaceVirtualFolder(const wxString &oldFolder, const wxString &newFolder)
946 {
947  int idx = m_VirtualFolders.Index(oldFolder);
948  if (idx != wxNOT_FOUND)
949  m_VirtualFolders[idx] = newFolder;
950  else
951  m_VirtualFolders.Add(newFolder);
952 
953  // now loop all project files and rename this virtual folder
954  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
955  {
956  ProjectFile* f = *it;
957  if (f && !f->virtual_path.IsEmpty())
958  {
959  if (f->virtual_path.StartsWith(oldFolder))
960  f->virtual_path.Replace(oldFolder, newFolder);
961  }
962  }
963 
964  SetModified(true);
965 }
966 
967 
969 {
970  m_VirtualFolders = folders;
971  for (size_t i = 0; i < m_VirtualFolders.GetCount(); ++i)
972  {
973  m_VirtualFolders[i].Replace(_T("/"), wxString(wxFILE_SEP_PATH));
974  m_VirtualFolders[i].Replace(_T("\\"), wxString(wxFILE_SEP_PATH));
975  }
976 }
977 
979 {
981 }
982 
984 {
986 }
987 
989 {
990  if (!m_Makefile.IsEmpty())
991  return m_Makefile;
992 
993  wxFileName makefile(m_Makefile);
994  makefile.Assign(m_Filename);
995  makefile.SetName(_T("Makefile"));
996  makefile.SetExt(_T(""));
997  makefile.MakeRelativeTo( GetBasePath() );
998 
999  m_Makefile = makefile.GetFullPath();
1000 
1001  return m_Makefile;
1002 }
1003 
1005 {
1006  if (m_MakefileExecutionDir != dir)
1007  {
1008  m_MakefileExecutionDir = dir;
1009  SetModified(true);
1010  }
1011 }
1012 
1014 {
1016  {
1017  wxFileName execution_dir( GetBasePath() );
1018  m_MakefileExecutionDir = execution_dir.GetFullPath();
1019  }
1020  return m_MakefileExecutionDir;
1021 }
1022 
1024 {
1025  if (!m_CustomMakefile)
1026  return GetBasePath();
1027 
1028  return GetMakefileExecutionDir();
1029 }
1030 
1032 {
1033  if (m_FileArray.GetCount() == 0)
1034  {
1035  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
1036  {
1037  if (!*it)
1038  continue;
1039  m_FileArray.Add((ProjectFile*)*it);
1040  }
1041  }
1042 
1043  if (index < 0 || index >= static_cast<int>(m_Files.size()))
1044  return NULL;
1045 
1046  return m_FileArray.Item(index);
1047 }
1048 
1049 ProjectFile* cbProject::GetFileByFilename(const wxString& filename, bool isRelative, bool isUnixFilename)
1050 {
1051  // m_ProjectFilesMap keeps UnixFilename(ProjectFile::relativeFilename)
1052  wxString tmp = filename;
1053  if (!isRelative)
1054  {
1055  // if the search is not relative, make it
1056  wxFileName fname(realpath(filename));
1057  fname.MakeRelativeTo( GetBasePath() );
1058  tmp = fname.GetFullPath();
1059  }
1060  else
1061  {
1062  // make sure filename doesn't start with ".\"
1063  // our own relative files don't have it, so the search would fail
1064  // this happens when importing MS projects...
1065  if (tmp.StartsWith(_T(".\\")) ||
1066  tmp.StartsWith(_T("./")))
1067  {
1068  tmp.Remove(0, 2);
1069  }
1070  }
1071 
1072  if (isUnixFilename)
1073  return m_ProjectFilesMap[tmp];
1074 
1075  return m_ProjectFilesMap[UnixFilename(tmp)];
1076 }
1077 
1079 {
1080  FilesList::iterator it = m_Files.begin();
1081  while (it != m_Files.end())
1082  {
1083  ProjectFile* f = *it++;
1085  if (ed && ed->GetModified())
1086  {
1087  if (!Manager::Get()->GetEditorManager()->QueryClose(ed))
1088  return false;
1089  }
1090  }
1091  return true;
1092 }
1093 
1094 bool cbProject::CloseAllFiles(bool dontsave)
1095 {
1096  // first try to close modified editors
1097 
1098  if (!dontsave && !QueryCloseAllFiles())
1099  return false;
1100 
1101  // now free the rest of the project files
1103  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
1104  {
1105  ProjectFile* f = *it;
1106  if (f)
1108  delete f;
1109  }
1110  m_FileArray.Clear();
1111  m_Files.clear();
1113 
1114  return true;
1115 }
1116 
1118 {
1119  int count = m_Files.size();
1120  FilesList::iterator it = m_Files.begin();
1121  while (it != m_Files.end())
1122  {
1123  ProjectFile* f = *it++;
1125  --count;
1126  }
1127  return count == 0;
1128 }
1129 
1130 int cbProject::SelectTarget(int initial, bool evenIfOne)
1131 {
1132  if (!evenIfOne && GetBuildTargetsCount() == 1)
1133  return 0;
1134 
1135  SelectTargetDlg dlg(nullptr, this, initial);
1136  PlaceWindow(&dlg);
1137  if (dlg.ShowModal() == wxID_OK)
1138  return dlg.GetSelection();
1139 
1140  return -1;
1141 }
1142 
1143 // Build targets
1144 
1146 {
1147  return AddBuildTarget(_T("default"));
1148 }
1149 
1151 {
1152  if (GetBuildTarget(targetName)) // Don't add the target if it exists
1153  return nullptr;
1154  ProjectBuildTarget* target = new ProjectBuildTarget(this);
1155  target->m_Filename = m_Filename; // really important
1156  target->SetTitle(targetName);
1157  target->SetCompilerID(GetCompilerID()); // same compiler as project's
1158  target->SetOutputFilename(wxFileName(GetOutputFilename()).GetFullName());
1159  target->SetWorkingDir(_T("."));
1160  target->SetObjectOutput(_T(".objs"));
1161  target->SetDepsOutput(_T(".deps"));
1162  m_Targets.Add(target);
1163 
1164  // remove any virtual targets with the same name
1165  if (HasVirtualBuildTarget(targetName))
1166  {
1167  RemoveVirtualBuildTarget(targetName);
1168  Manager::Get()->GetLogManager()->LogWarning(F(_T("Deleted existing virtual target '%s' because real target was added with the same name"), targetName.wx_str()));
1169  }
1170 
1171  SetModified(true);
1172 
1175  return target;
1176 }
1177 
1178 bool cbProject::RenameBuildTarget(int index, const wxString& targetName)
1179 {
1180  ProjectBuildTarget* target = GetBuildTarget(index);
1181  if (target)
1182  {
1183  wxString oldTargetName = target->GetTitle();
1184 
1185  // rename target if referenced in any virtual target too
1186  for (VirtualBuildTargetsMap::iterator it = m_VirtualTargets.begin(); it != m_VirtualTargets.end(); ++it)
1187  {
1188  wxArrayString& tgts = it->second;
1189  index = tgts.Index(target->GetTitle());
1190  if (index != -1)
1191  tgts[index] = targetName;
1192  }
1193 
1194  // rename target for all files that reference it
1195  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
1196  {
1197  ProjectFile* pf = *it;
1198  pf->RenameBuildTarget(target->GetTitle(), targetName);
1199  }
1200 
1201  // finally rename the target
1202  target->SetTitle(targetName);
1203  SetModified(true);
1204  NotifyPlugins(cbEVT_BUILDTARGET_RENAMED, targetName, oldTargetName);
1206  return true;
1207  }
1208  return false;
1209 }
1210 
1211 bool cbProject::RenameBuildTarget(const wxString& oldTargetName, const wxString& newTargetName)
1212 {
1213  return RenameBuildTarget(IndexOfBuildTargetName(oldTargetName), newTargetName);
1214 }
1215 
1217 {
1218  ProjectBuildTarget* newTarget = nullptr;
1219  ProjectBuildTarget* target = GetBuildTarget(index);
1220  if (target)
1221  {
1222  newTarget = new ProjectBuildTarget(*target);
1223  wxString newTargetName = !newName.IsEmpty() ? newName : (_("Copy of ") + target->GetTitle());
1224  newTarget->SetTitle(newTargetName);
1225  // just notify the files of this target that they belong to the new target too
1226  for (FilesList::iterator it = newTarget->GetFilesList().begin(); it != newTarget->GetFilesList().end(); ++it)
1227  {
1228  ProjectFile* pf = *it;
1229  pf->AddBuildTarget(newTargetName);
1230  }
1231  SetModified(true);
1232  m_Targets.Add(newTarget);
1233  // send also the old target name, so plugins see that the target is duplicated and not a new one added
1234  // so that plugin specific parameters can be copied, too.
1235  NotifyPlugins(cbEVT_BUILDTARGET_ADDED, newName, target->GetTitle());
1237  }
1238  return newTarget;
1239 }
1240 
1242 {
1243  return DuplicateBuildTarget(IndexOfBuildTargetName(targetName), newName);
1244 }
1245 
1247 {
1248  ProjectBuildTarget* target = GetBuildTarget(index);
1249  if (!target)
1250  return false;
1251  return ExportTargetAsProject(target->GetTitle());
1252 }
1253 
1255 {
1256  ProjectBuildTarget* target = GetBuildTarget(targetName);
1257  if (!target)
1258  return false;
1259 
1260  // ask for the new project's name
1261  wxString newName = cbGetTextFromUser(_("Please enter the new project's name (no path, no extension)."),
1262  _("Export target as new project"),
1263  target->GetTitle());
1264  if (newName.IsEmpty())
1265  return false;
1266  wxFileName fname(GetFilename());
1267  fname.SetName(newName);
1268 
1269  Save();
1270  bool alreadyModified = GetModified();
1271  wxString oldTitle = GetTitle();
1272  SetTitle(targetName);
1273 
1274  ProjectLoader loader(this);
1275  bool ret = loader.ExportTargetAsProject(fname.GetFullPath(), target->GetTitle(), m_pExtensionsElement);
1276 
1277  SetTitle(oldTitle);
1278  if (!alreadyModified)
1279  SetModified(false);
1280 
1281  return ret;
1282 }
1283 
1285 {
1286  ProjectBuildTarget* target = GetBuildTarget(index);
1287  if (target)
1288  {
1289  const wxString targetTitle = target->GetTitle();
1290 
1291  // remove target from any virtual targets it belongs to
1292  for (VirtualBuildTargetsMap::iterator it = m_VirtualTargets.begin(); it != m_VirtualTargets.end(); ++it)
1293  {
1294  wxArrayString& tgts = it->second;
1295  int virt_idx = tgts.Index(targetTitle);
1296  if (virt_idx != -1)
1297  tgts.RemoveAt(virt_idx);
1298  }
1299 
1300  // remove target from any project files that reference it
1301  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
1302  {
1303  ProjectFile* pf = *it;
1304  pf->RemoveBuildTarget(targetTitle);
1305  }
1306 
1307  // notify plugins, before the target is deleted, to make a cleanup possible before the target is really deleted
1309  // finally remove the target
1310  delete target;
1311  m_Targets.RemoveAt(index);
1312  SetModified(true);
1314  return true;
1315  }
1316  return false;
1317 }
1318 
1320 {
1321  return RemoveBuildTarget(IndexOfBuildTargetName(targetName));
1322 }
1323 
1324 int cbProject::IndexOfBuildTargetName(const wxString& targetName) const
1325 {
1326  for (unsigned int i = 0; i < m_Targets.GetCount(); ++i)
1327  {
1328  ProjectBuildTarget* target = m_Targets[i];
1329  if (target->GetTitle().Matches(targetName))
1330  return i;
1331  }
1332  return -1;
1333 }
1334 
1335 bool cbProject::BuildTargetValid(const wxString& name, bool virtuals_too) const
1336 {
1337  if (virtuals_too && HasVirtualBuildTarget(name))
1338  return true;
1339  else if (IndexOfBuildTargetName(name) != -1)
1340  return true;
1341 
1342  return false;
1343 }
1344 
1346 {
1347  if (virtuals_too && !m_VirtualTargets.empty())
1348  return m_VirtualTargets.begin()->first;
1349  else if (m_Targets.GetCount() && m_Targets[0])
1350  return m_Targets[0]->GetTitle();
1351 
1352  return wxEmptyString;
1353 }
1354 
1356 {
1357  if (name == m_ActiveTarget)
1358  return true;
1359 
1360  wxString oldActiveTarget = m_ActiveTarget;
1361  m_ActiveTarget = name;
1362 
1363  bool valid = BuildTargetValid(name);
1364 
1365  if (!valid) // no target (virtual or real) by that name
1367 
1369 
1370  return valid;
1371 }
1372 
1374 {
1375  return m_ActiveTarget;
1376 }
1377 
1379 {
1380  if (name == m_DefaultExecuteTarget)
1381  return;
1382 
1383  m_DefaultExecuteTarget = name;
1384  SetModified(true);
1385 }
1386 
1388 {
1389  return m_DefaultExecuteTarget;
1390 }
1391 
1393 {
1394  if (index >= 0 && index < (int)m_Targets.GetCount())
1395  return m_Targets[index];
1396  return nullptr;
1397 }
1398 
1400 {
1401  int idx = IndexOfBuildTargetName(targetName);
1402  return GetBuildTarget(idx);
1403 }
1404 
1406 {
1407  LogManager* msgMan = Manager::Get()->GetLogManager();
1408  if (nameOrder.GetCount() != m_Targets.GetCount())
1409  {
1410  msgMan->DebugLog(F(_T("cbProject::ReOrderTargets() : Count does not match (%lu sent, %lu had)..."),
1411  static_cast<unsigned long>(nameOrder.GetCount()),
1412  static_cast<unsigned long>(m_Targets.GetCount())));
1413  return;
1414  }
1415 
1416  for (unsigned int i = 0; i < nameOrder.GetCount(); ++i)
1417  {
1418  ProjectBuildTarget* target = GetBuildTarget(nameOrder[i]);
1419  if (!target)
1420  {
1421  msgMan->DebugLog(F(_T("cbProject::ReOrderTargets() : Target \"%s\" not found..."), nameOrder[i].wx_str()));
1422  break;
1423  }
1424 
1425  m_Targets.Remove(target);
1426  m_Targets.Insert(target, i);
1427 
1428  // we have to re-order the targets which are kept inside
1429  // the virtual targets array too!
1430  VirtualBuildTargetsMap::iterator it;
1431  for (it = m_VirtualTargets.begin(); it != m_VirtualTargets.end(); ++it)
1432  {
1433  wxArrayString& vt = it->second;
1434  if (vt.Index(nameOrder[i]) != wxNOT_FOUND)
1435  {
1436  vt.Remove(nameOrder[i]);
1437  vt.Insert(nameOrder[i], (vt.Count()<=i) ? vt.Count()-1 : i);
1438  }
1439  }
1440  }
1441  SetModified(true);
1442 }
1443 
1445 {
1447 }
1448 
1450 {
1451  if (targets.GetCount() == 0)
1452  {
1453  Manager::Get()->GetLogManager()->LogWarning(F(_T("Can't define virtual build target '%s': Group of build targets is empty!"), alias.wx_str()));
1454  return false;
1455  }
1456 
1457  ProjectBuildTarget* existing = GetBuildTarget(alias);
1458  if (existing)
1459  {
1460  Manager::Get()->GetLogManager()->LogWarning(F(_T("Can't define virtual build target '%s': Real build target exists with that name!"), alias.wx_str()));
1461  return false;
1462  }
1463 
1464  m_VirtualTargets[alias] = targets;
1465  SetModified(true);
1467  return true;
1468 }
1469 
1471 {
1472  return m_VirtualTargets.find(alias) != m_VirtualTargets.end();
1473 }
1474 
1476 {
1477  VirtualBuildTargetsMap::iterator it = m_VirtualTargets.find(alias);
1478  if (it == m_VirtualTargets.end())
1479  return false;
1480 
1481  m_VirtualTargets.erase(it);
1482  SetModified(true);
1484  return true;
1485 }
1486 
1488 {
1489  wxArrayString result;
1490  for (VirtualBuildTargetsMap::const_iterator it = m_VirtualTargets.begin(); it != m_VirtualTargets.end(); ++it)
1491  result.Add(it->first);
1492 
1493  return result;
1494 }
1495 
1497 {
1498  static wxArrayString resultIfError;
1499 
1500  VirtualBuildTargetsMap::const_iterator it = m_VirtualTargets.find(alias);
1501  if (it == m_VirtualTargets.end())
1502  return resultIfError;
1503 
1504  return it->second;
1505 }
1506 
1508 {
1509  wxArrayString result;
1510 
1511  VirtualBuildTargetsMap::const_iterator it = m_VirtualTargets.find(alias);
1512  if (it == m_VirtualTargets.end())
1513  return result;
1514  ExpandVirtualBuildTargetGroup(alias, result);
1515 
1516  return result;
1517 }
1518 
1520 {
1521  // virtual not there?
1522  if (!HasVirtualBuildTarget(alias))
1523  return false;
1524 
1525  // real targets can be added safely (as long as they 're unique)
1526  if (!HasVirtualBuildTarget(target))
1527  return true;
1528 
1529  // virtual targets are checked in two ways:
1530  // 1) it is checked if it contains alias
1531  // 2) all its virtual targets are recursively checked if they contain alias
1532  const wxArrayString& group = GetVirtualBuildTargetGroup(target);
1533  if (group.Index(alias) != wxNOT_FOUND)
1534  return false;
1535 
1536  for (size_t i = 0; i < group.GetCount(); ++i)
1537  {
1538  // only virtuals
1539  if (HasVirtualBuildTarget(group[i]))
1540  {
1541  if (!CanAddToVirtualBuildTarget(group[i], alias))
1542  return false;
1543  }
1544  }
1545  return true;
1546 }
1547 
1549 {
1550  const wxArrayString& group = GetVirtualBuildTargetGroup(alias);
1551  for (size_t i = 0; i < group.GetCount(); ++i)
1552  {
1553  // real targets get added
1554  if (IndexOfBuildTargetName(group[i]) != -1)
1555  {
1556  if (result.Index(group[i]) == wxNOT_FOUND)
1557  result.Add(group[i]);
1558  }
1559  // virtual targets recurse
1560  else
1561  ExpandVirtualBuildTargetGroup(group[i], result);
1562  }
1563 }
1564 
1566 {
1567  bool changed = m_ExtendedObjectNamesGeneration != ext;
1568 
1569  // update it now because SetObjName() below will call GetExtendedObjectNamesGeneration()
1570  // so it must be up-to-date
1572 
1573  if (changed)
1574  {
1575  for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
1576  {
1577  ProjectFile* f = *it;
1579  f->UpdateFileDetails();
1580  }
1581 
1582  SetModified(true);
1583  }
1584 }
1585 
1587 {
1589 }
1590 
1591 void cbProject::SetNotes(const wxString& notes)
1592 {
1593  if (m_Notes != notes)
1594  {
1595  m_Notes = notes;
1596  SetModified(true);
1597  }
1598 }
1599 
1601 {
1602  return m_Notes;
1603 }
1604 
1606 {
1607  if (m_AutoShowNotesOnLoad != show)
1608  {
1609  m_AutoShowNotesOnLoad = show;
1610  SetModified(true);
1611  }
1612 }
1613 
1615 {
1616  return m_AutoShowNotesOnLoad;
1617 }
1618 
1620 {
1621  if (m_CheckForExternallyModifiedFiles != check)
1622  {
1624  SetModified(true);
1625  }
1626 }
1627 
1629 {
1631 }
1632 
1633 void cbProject::ShowNotes(bool nonEmptyOnly, bool editable)
1634 {
1635  if (!editable && nonEmptyOnly && m_Notes.IsEmpty())
1636  return;
1637 
1638  GenericMultiLineNotesDlg dlg(Manager::Get()->GetAppWindow(),
1639  _("Notes about ") + m_Title,
1640  m_Notes,
1641  !editable);
1642  PlaceWindow(&dlg);
1643  if (dlg.ShowModal() == wxID_OK)
1644  {
1645  if (editable)
1646  SetNotes(dlg.GetNotes());
1647  }
1648 }
1649 
1650 void cbProject::SetTitle(const wxString& title)
1651 {
1652  if ( title != GetTitle() )
1653  {
1656  }
1657 }
1658 
1660 {
1661  if (!m_pExtensionsElement)
1662  m_pExtensionsElement = new TiXmlElement(cbU2C(_T("Extensions")));
1663  return m_pExtensionsElement;
1664 }
1665 
1666 void cbProject::AddToExtensions(const wxString& stringDesc)
1667 {
1668  // sample stringDesc:
1669  // node/+subnode/subsubnode:attr=val
1670 
1671  TiXmlElement* elem = GetExtensionsNode()->ToElement();
1672  size_t pos = 0;
1673  while (true)
1674  {
1675  // ignore consecutive slashes
1676  while (pos < stringDesc.Length() && stringDesc.GetChar(pos) == _T('/'))
1677  {
1678  ++pos;
1679  }
1680 
1681  // find next slash or colon
1682  size_t nextPos = pos;
1683  while (nextPos < stringDesc.Length() && stringDesc.GetChar(++nextPos) != _T('/') && stringDesc.GetChar(nextPos) != _T(':'))
1684  ;
1685 
1686  wxString current = stringDesc.Mid(pos, nextPos - pos);
1687  if (current.IsEmpty() || current[0] == _T(':')) // abort on invalid case: "node/:attr=val" (consecutive "/:")
1688  break;
1689 
1690  // find or create the subnode
1691  bool forceAdd = current[0] == _T('+');
1692  if (forceAdd)
1693  current.Remove(0, 1); // remove '+'
1694  TiXmlElement* sub = !forceAdd ? elem->FirstChildElement(cbU2C(current)) : nullptr;
1695  if (!sub)
1696  {
1697  sub = elem->InsertEndChild(TiXmlElement(cbU2C(current)))->ToElement();
1698  SetModified(true);
1699  }
1700  elem = sub;
1701 
1702  // last node?
1703  if (stringDesc.GetChar(nextPos) == _T(':'))
1704  {
1705  // yes, just parse the attribute now
1706  pos = nextPos + 1; // skip the colon
1707  nextPos = pos;
1708  while (nextPos < stringDesc.Length() && stringDesc.GetChar(++nextPos) != _T('='))
1709  ;
1710  if (pos == nextPos || nextPos == stringDesc.Length())
1711  {
1712  // invalid attribute
1713  }
1714  else
1715  {
1716  wxString key = stringDesc.Mid(pos, nextPos - pos);
1717  wxString val = stringDesc.Mid(nextPos + 1, stringDesc.Length() - nextPos - 1);
1718  sub->SetAttribute(cbU2C(key), cbU2C(val));
1719  SetModified(true);
1720  }
1721 
1722  // all done
1723  break;
1724  }
1725 
1726  pos = nextPos; // prepare for next loop
1727  }
1728 }
1729 
1731 {
1732  for (ProjectFiles::iterator it = m_ProjectFilesMap.begin(); it != m_ProjectFilesMap.end(); ++it)
1733  {
1734  ProjectFile* itpf = it->second;
1735  if (itpf == pf)
1736  {
1737  // got it
1738  m_ProjectFilesMap.erase(it);
1740  break;
1741  }
1742  }
1743 }
1744 
1745 void cbProject::SetGlobs(const std::vector<Glob>& globs)
1746 {
1747  m_Globs = globs;
1748 }
1749 
1750 std::vector<cbProject::Glob> cbProject::GetGlobs() const
1751 {
1752  return m_Globs;
1753 }
1754 
1756 {
1757  if (!target)
1758  return wxEmptyString;
1759 
1760  Compiler* compiler = CompilerFactory::GetCompiler(target->GetCompilerID());
1761  if (compiler)
1762  {
1763  CompilerCommandGenerator* generator = compiler->GetCommandGenerator(project);
1764  wxString libPath;
1765  const wxString libPathSep = platform::windows ? _T(";") : _T(":");
1766  libPath << _T(".") << libPathSep;
1767  libPath << GetStringFromArray(generator->GetLinkerSearchDirs(target), libPathSep);
1768  if (!libPath.IsEmpty() && libPath.Mid(libPath.Length() - 1, 1) == libPathSep)
1769  libPath.Truncate(libPath.Length() - 1);
1770 
1771  delete generator;
1772  return libPath;
1773  }
1774  return wxEmptyString;
1775 }
1776 
1777 wxString cbMergeLibPaths(const wxString &oldPath, const wxString &newPath)
1778 {
1779  wxString result = newPath;
1780  const wxString libPathSep = platform::windows ? _T(";") : _T(":");
1781  if (!newPath.IsEmpty() && newPath.Mid(newPath.Length() - 1, 1) != libPathSep)
1782  result << libPathSep;
1783  result << oldPath;
1784  return result;
1785 }
ProjectFile * GetFileByFilename(const wxString &filename, bool isRelative=true, bool isUnixFilename=false)
Access a file of the project.
Definition: cbproject.cpp:1049
wxString F(const wxChar *msg,...)
sprintf-like function
Definition: logmanager.h:20
ProjectBuildTarget * DuplicateBuildTarget(int index, const wxString &newName=wxEmptyString)
Duplicate a build target.
Definition: cbproject.cpp:1216
int editorTabPos
The position of the editor-tab for this file.
Definition: projectfile.h:178
cbEditor * IsBuiltinOpen(const wxString &filename)
Definition: editormanager.h:92
static void Display(const wxString &title, const wxString &message, unsigned int delay=5000, unsigned int hysteresis=1)
Definition: infowindow.cpp:294
wxArrayString m_ExpandedNodes
Definition: cbproject.h:708
wxString relativeToCommonTopLevelPath
The relative filename to the common top-level path.
Definition: projectfile.h:135
bool m_CurrentlyLoading
Definition: cbproject.h:715
EVTIMPORT const wxEventType cbEVT_BUILDTARGET_RENAMED
Definition: sdk_events.cpp:118
wxArrayString generatedFiles
the native language files this command generates that should be further compiled
Definition: compiler.h:264
void SetMakefileCustom(bool custom)
Mark if the project should use a custom Makefile for compilation.
Definition: cbproject.cpp:194
void Remove(const wxString &sz)
EVTIMPORT const wxEventType cbEVT_PROJECT_END_ADD_FILES
Definition: sdk_events.cpp:101
bool Matches(const wxString &mask) const
EVTIMPORT const wxEventType cbEVT_PROJECT_RENAMED
Definition: sdk_events.cpp:109
FilesList m_Files
Definition: cbproject.h:706
virtual void SetTitle(const wxString &title)
Set the target&#39;s title.
void ClearAllProperties()
This resets the project to a clear state.
Definition: cbproject.cpp:236
void SetVirtualFolders(const wxArrayString &folders)
Set the virtual folders list.
Definition: cbproject.cpp:968
ProjectBuildTarget * AddDefaultBuildTarget()
Definition: cbproject.cpp:1145
ProjectBuildTarget * m_CurrentlyCompilingTarget
Definition: cbproject.h:723
wxString relativeFilename
The relative (to the project) filename of this file.
Definition: projectfile.h:131
const DLLIMPORT wxString CODEBLOCKS_EXT
std::vector< Glob > m_Globs
Definition: cbproject.h:705
bool Save(const wxString &filename) override
Save a file.
#define wxICON_WARNING
virtual void SetObjectOutput(const wxString &dirname)
Set the target&#39;s objects output dir.
void Delete(std::vector< T > &s)
Definition: safedelete.h:20
void SetDefaultExecuteTarget(const wxString &name)
Set the build target index which will be pre-selected when the "Select target" dialog appears when ru...
Definition: cbproject.cpp:1378
void Assign(const wxFileName &filepath)
Generate command-lines needed to produce a build.
void SetFullName(const wxString &fullname)
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
void RestoreTreeState(wxTreeCtrl *tree)
Convenience function for remembering the project&#39;s tree state when refreshing it. ...
Definition: cbproject.cpp:983
void DebugLogError(const wxString &msg)
Definition: logmanager.h:147
void ReOrderTargets(const wxArrayString &nameOrder)
Reorder the list of build targets.
Definition: cbproject.cpp:1405
int ReadInt(const wxString &name, int defaultVal=0)
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
bool DefineVirtualBuildTarget(const wxString &alias, const wxArrayString &targets)
Define a new virtual build target.
Definition: cbproject.cpp:1449
int IndexOfBuildTargetName(const wxString &targetName) const
Definition: cbproject.cpp:1324
void Touch()
Sets the last modification time for the project to &#39;now&#39;.
Definition: cbproject.cpp:428
void BeginRemoveFiles()
Notify that file(s) will be removed shortly.
Definition: cbproject.cpp:607
void SetShowNotesOnLoad(bool show)
Set show project notes on load automatically.
Definition: cbproject.cpp:1605
#define wxICON_ERROR
virtual const CompilerTool * GetCompilerTool(CommandType ct, const wxString &fileExtension=wxEmptyString) const
Get a compiler tool based on CommandType.
Definition: compiler.cpp:334
bool wxFileExists(const wxString &filename)
const wxString & GetObjName()
void LogWarning(const wxString &msg, int i=app_log)
Definition: logmanager.h:141
DLLIMPORT wxString cbGetTextFromUser(const wxString &message, const wxString &caption=cbGetTextFromUserPromptStr, const wxString &default_value=wxEmptyString, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord, bool centre=true)
Definition: globals.cpp:1465
wxFileName file
The full filename of this file.
Definition: projectfile.h:126
bool QueryCloseAllFiles()
Act like closing all project files, but don&#39;t do it.
Definition: cbproject.cpp:1078
bool m_AutoShowNotesOnLoad
Definition: cbproject.h:729
int GetSelection() const
bool compile
Compile flag.
Definition: projectfile.h:138
bool ReadBool(const wxString &name, bool defaultVal=false)
EVTIMPORT const wxEventType cbEVT_BUILDTARGET_SELECTED
Definition: sdk_events.cpp:119
static wxDateTime Now()
bool Open(const wxString &filename)
int Index(const wxString &sz, bool bCase=true, bool bFromEnd=false) const
void SetModified(bool modified=true) override
Mark the project as modified or not.
Definition: cbproject.cpp:179
void SetCurrentlyCompilingTarget(ProjectBuildTarget *bt)
Set the currently compiling target.
Definition: cbproject.cpp:1444
wxArrayString m_VirtualFolders
Definition: cbproject.h:713
bool GetCheckForExternallyModifiedFiles() const
Get check for externally modified files.
Definition: cbproject.cpp:1628
FileManager * GetFileManager() const
Definition: manager.cpp:479
size_t Length() const
wxCStrData c_str() const
bool wxDirExists(const wxString &dirname)
virtual void Activate()
Activate this editor.
Definition: editorbase.cpp:175
wxString GetExecutionDir()
Definition: cbproject.cpp:1023
long Time() const
static Compiler * GetCompiler(size_t index)
bool CanAddToVirtualBuildTarget(const wxString &alias, const wxString &target)
Checks if a build target (virtual or real) can be added to a virtual build target, without causing a circular-reference.
Definition: cbproject.cpp:1519
void NotifyPlugins(wxEventType type, const wxString &targetName=wxEmptyString, const wxString &oldTargetName=wxEmptyString)
Definition: cbproject.cpp:120
#define _T(string)
FileType
Known file types.
Definition: globals.h:49
static const wxString & GetDefaultCompilerID()
EVTIMPORT const wxEventType cbEVT_PROJECT_BEGIN_ADD_FILES
Definition: sdk_events.cpp:100
bool Close(const wxString &filename, bool dontsave=false)
void EndAddFiles()
Notify that file(s) addition finished.
Definition: cbproject.cpp:600
const DLLIMPORT wxString C_EXT
bool SaveAs()
Save the project under a different name.
Definition: cbproject.cpp:433
DLLIMPORT wxString GetStringFromArray(const wxArrayString &array, const wxString &separator=DEFAULT_ARRAY_SEP, bool SeparatorAtEnd=true)
Definition: globals.cpp:122
bool IsAbsolute(wxPathFormat format=wxPATH_NATIVE) const
DLLIMPORT FileType FileTypeOf(const wxString &filename)
Definition: globals.cpp:285
void ReplaceVirtualFolder(const wxString &oldFolder, const wxString &newFolder)
Replaced the oldFolder with newFolder or appends newFolder to the end of the list if oldFolder is not...
Definition: cbproject.cpp:945
Compile object command, e.g. "$compiler $options $includes -c $file -o $object".
Definition: compiler.h:168
EVTIMPORT const wxEventType cbEVT_PROJECT_SAVE
Definition: sdk_events.cpp:98
wxString & Remove(size_t pos)
wxString GetName() const
void CalculateCommonTopLevelPath()
Calculates the top-level path common to all project files.
Definition: cbproject.cpp:319
void EndRemoveFiles()
Notify that file(s) removal finished.
Definition: cbproject.cpp:614
wxString m_BasePath
Definition: cbproject.h:717
virtual void AddToExtensions(const wxString &stringDesc)
Convenience function (mainly for scripts) to add nodes/attributes under the <Extensions> node...
Definition: cbproject.cpp:1666
ProjectFiles m_ProjectFilesMap
Definition: cbproject.h:722
void UpdateFileDetails(ProjectBuildTarget *target=nullptr)
This is called automatically when adding/removing build targets.
void SetAutoGeneratedBy(ProjectFile *TheFile)
If this is an auto-generated file, set the file which is generating it?
Definition: projectfile.h:204
#define wxNOT_FOUND
Represents a file in a Code::Blocks project.
Definition: projectfile.h:39
bool m_CustomMakefile
Definition: cbproject.h:702
A generic Code::Blocks event.
Definition: sdk_events.h:20
In the objects output dir, along with other object files.
Definition: cbproject.h:87
virtual wxString GetOutputFilename()
Read the target&#39;s output filename.
bool RemoveFile(ProjectFile *pf)
Remove a file from the project.
Definition: cbproject.cpp:860
void BeginAddFiles()
Notify that file(s) will be added shortly.
Definition: cbproject.cpp:593
virtual void SetCompilerID(const wxString &id)
! Set the flag if the host app should be run in terminal
EditorManager * GetEditorManager() const
Definition: manager.cpp:434
DLLIMPORT const wxWX2MBbuf cbU2C(const wxString &str)
Return multibyte (C string) representation of the string.
Definition: globals.cpp:743
bool CloseAllFiles(bool dontsave=false)
Close all project files.
Definition: cbproject.cpp:1094
wxArrayString m_CompilerOptions
bool ExportTargetAsProject(const wxString &filename, const wxString &onlyTarget, TiXmlElement *pExtensions)
Export a target as a new project.
const wxString & GetMakefile()
Definition: cbproject.cpp:988
void RemoveVirtualFolders(const wxString &folder)
Remove all virtual folders starting with folder.
Definition: cbproject.cpp:924
ProjectManager * GetProjectManager() const
Functions returning pointers to the respective sub-manager instances.
Definition: manager.cpp:429
bool MakeRelativeTo(const wxString &pathBase=wxEmptyString, wxPathFormat format=wxPATH_NATIVE)
void SetCompilerID(const wxString &id) override
! Set the flag if the host app should be run in terminal
Definition: cbproject.cpp:129
virtual void ProjectFileRenamed(ProjectFile *pf)
Internal use only.
Definition: cbproject.cpp:1730
~cbProject() override
Destructor.
Definition: cbproject.cpp:111
wxString m_Notes
Definition: cbproject.h:728
DLLIMPORT wxString UnixFilename(const wxString &filename, wxPathFormat format=wxPATH_NATIVE)
Definition: globals.cpp:228
bool FileModified()
Definition: projectloader.h:70
wxString GetExt() const
void Insert(wxString lItem, size_t nIndex, size_t copies=1)
Represents a Code::Blocks project.
Definition: cbproject.h:96
const wxString & GetActiveBuildTarget() const
Definition: cbproject.cpp:1373
virtual const wxString & GetFilename() const
void RenameBuildTarget(const wxString &oldTargetName, const wxString &newTargetName)
Rename a build target this file belongs in.
TiXmlElement * m_pExtensionsElement
Definition: cbproject.h:734
null_pointer_t nullptr
Definition: nullptr.cpp:16
bool AppendUniqueVirtualFolder(const wxString &folder)
Appends a new virtual folder to the end of the list only if it doesn&#39;t exists.
Definition: cbproject.cpp:913
Struct for compiler/linker commands.
Definition: compiler.h:249
virtual void SetOutputFilename(const wxString &filename)
Set the target&#39;s output filename.
wxString objectExtension
Definition: compiler.h:217
wxString GetMakefileExecutionDir()
Definition: cbproject.cpp:1013
DLLIMPORT wxString cbC2U(const char *str)
Return str as a proper unicode-compatible string.
Definition: globals.cpp:733
virtual const wxString & GetTitle() const
Read the target&#39;s title.
EVTIMPORT const wxEventType cbEVT_PROJECT_BEGIN_REMOVE_FILES
Definition: sdk_events.cpp:102
void RemoveBuildTarget(const wxString &targetName)
Remove this file from the specified build target.
wxString Left(size_t count) const
wxArrayString m_LinkerOptions
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
void Open()
Definition: cbproject.cpp:264
wxString GetVolume() const
virtual void SetModified(bool modified)
void SaveTreeState(wxTreeCtrl *tree)
Convenience function for remembering the project&#39;s tree state when refreshing it. ...
Definition: cbproject.cpp:978
bool Open(const wxString &filename) override
Open a file.
void SetCheckForExternallyModifiedFiles(bool check)
Set check for externally modified files.
Definition: cbproject.cpp:1619
bool BuildTargetValid(const wxString &name, bool virtuals_too=true) const
Is there a build target (virtual or real) by name?
Definition: cbproject.cpp:1335
void ShowNotes(bool nonEmptyOnly, bool editable=false)
Show project notes now.
Definition: cbproject.cpp:1633
void HideNotebook()
Hides the editor notebook for layout purposes.
bool IsSameAs(const wxString &s, bool caseSensitive=true) const
static bool IsBatchBuild()
Definition: manager.h:66
static const wxString sep
wxString cbGetDynamicLinkerPathForTarget(cbProject *project, ProjectBuildTarget *target)
Returns a string valid to be used as LD_LIBRARY_PATH (or equivalent).
Definition: cbproject.cpp:1755
Base class that all "editors" should inherit from.
Definition: editorbase.h:30
LogManager * GetLogManager() const
Definition: manager.cpp:439
VirtualBuildTargetsMap m_VirtualTargets
Definition: cbproject.h:696
wxString & Truncate(size_t len)
wxTreeItemId m_ProjectNode
Definition: cbproject.h:711
EVTIMPORT const wxEventType cbEVT_BUILDTARGET_REMOVED
Definition: sdk_events.cpp:117
virtual wxString GetBasePath() const
Read the target&#39;s base path, e.g. if GetFilename() returns "/usr/local/bin/xxx", base path will retur...
static wxUniChar GetPathSeparator(wxPathFormat format=wxPATH_NATIVE)
virtual void SetWorkingDir(const wxString &dirname)
Set the target&#39;s working dir on execution (valid only for executable targets)
const wxStringCharType * wx_str() const
virtual int ShowModal()
wxString CreateUniqueFilename()
Definition: cbproject.cpp:203
bool Save(const wxString &filename)
const wxArrayString & GetVirtualBuildTargetGroup(const wxString &alias) const
Access a virtual build target&#39;s group of build targets.
Definition: cbproject.cpp:1496
wxString wxEmptyString
wxString Right(size_t count) const
#define wxOK
bool QueryClose(EditorBase *editor)
wxString m_LastSavedActiveTarget
Definition: cbproject.h:699
bool SaveAllFiles()
Save all project files.
Definition: cbproject.cpp:1117
EVTIMPORT const wxEventType cbEVT_PROJECT_TARGETS_MODIFIED
Definition: sdk_events.cpp:108
const wxString & GetNotes() const
Get notes on the project.
Definition: cbproject.cpp:1600
ProjectFile * AddFile(const wxString &targetName, const wxString &filename, bool compile=true, bool link=true, unsigned short int weight=50)
Add a file to the project.
Definition: cbproject.cpp:621
MacrosManager * GetMacrosManager() const
Definition: manager.cpp:454
cbEditor * Open(const wxString &filename, int pos=0, ProjectFile *data=nullptr)
bool editorOpen
If true, the file is open inside an editor.
Definition: projectfile.h:148
static bool Access(const wxString &name, wxFile::OpenMode mode)
const wxString & _(const wxString &string)
void ReplaceMacros(wxString &buffer, ProjectBuildTarget *target=nullptr, bool subrequest=false)
bool m_CheckForExternallyModifiedFiles
Definition: cbproject.h:730
int GetBuildTargetsCount()
Definition: cbproject.h:200
virtual FilesList & GetFilesList()
Provides an easy way to iterate all the files belonging in this target.
EVTIMPORT const wxEventType cbEVT_PROJECT_END_REMOVE_FILES
Definition: sdk_events.cpp:103
bool m_ExtendedObjectNamesGeneration
Definition: cbproject.h:727
cb_must_consume_result LoaderBase * Load(const wxString &file, bool reuseEditors=false)
Loads a file, once this function is called, the actually loading process is done in the worker thread...
ProjectFile * GetFile(int index)
Access a file of the project.
Definition: cbproject.cpp:1031
ProjectFilesVector generatedFiles
Auto-generated files when compiling this file.
Definition: projectfile.h:207
wxString compilerVar
The compiler variable used for this file (e.g CPP, CC, etc).
Definition: projectfile.h:187
wxArrayString GetVirtualBuildTargets() const
Get a list of all defined virtual build targets.
Definition: cbproject.cpp:1487
void SetGlobs(const std::vector< Glob > &globs)
Set the globs to the project, this are directory paths do retrieve files from to be added to the proj...
Definition: cbproject.cpp:1745
virtual void SetDepsOutput(const wxString &dirname)
Set the target&#39;s dependencies output dir.
wxArrayString GetExpandedVirtualBuildTargetGroup(const wxString &alias) const
Access a virtual build target&#39;s expanded group of build targets.
Definition: cbproject.cpp:1507
ProjectBuildTarget * GetBuildTarget(int index)
Access a build target.
Definition: cbproject.cpp:1392
Code::Blocks project file loader.
Definition: projectloader.h:22
DLLIMPORT wxString GetFilterString(const wxString &ext=wxEmptyString)
Generates and returns the filter string for use in file dialogs.
Definition: filefilters.cpp:60
Compile Win32 resources command, e.g. "$rescomp -i $file -J rc -o $resource_output -O coff $includes"...
Definition: compiler.h:170
Abstract base class for compilers.
Definition: compiler.h:274
const wxString & GetDefaultExecuteTarget() const
Definition: cbproject.cpp:1387
const wxArrayString & GetVirtualFolders() const
Get a list of the virtual folders.
Definition: cbproject.cpp:908
bool GetExtendedObjectNamesGeneration() const
Gets object names generation mode (extended/normal).
Definition: cbproject.cpp:1586
void SetProjectFile(ProjectFile *project_file, bool preserve_modified=false)
Set the ProjectFile pointer associated with this editor.
Definition: cbeditor.cpp:885
void ExpandVirtualBuildTargetGroup(const wxString &alias, wxArrayString &result) const
Definition: cbproject.cpp:1548
A file editor.
Definition: cbeditor.h:43
virtual const wxArrayString & GetLinkerSearchDirs(ProjectBuildTarget *target)
Get the full linker dirs used in the actual command line.
wxString m_MakefileExecutionDir
Definition: cbproject.h:703
bool IsEmpty() const
DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode=pdlBest, bool enforce=false)
Definition: globals.cpp:1177
void Clear()
wxArrayString m_SelectedNodes
Definition: cbproject.h:709
wxString GetPath(int flags=wxPATH_GET_VOLUME, wxPathFormat format=wxPATH_NATIVE) const
void ShowNotebook()
Shows the previously hidden editor notebook.
virtual const wxString & GetCompilerID() const
Read the target&#39;s compiler.
wxString m_CommonTopLevelPath
Definition: cbproject.h:716
bool GetShowNotesOnLoad() const
Get show project notes on load automatically.
Definition: cbproject.cpp:1614
bool LoadLayout()
Load the project&#39;s layout.
Definition: cbproject.cpp:513
void Log(const wxString &msg, int i=app_log, Logger::level lv=Logger::info)
Definition: logmanager.h:140
wxString GetFullName() const
BuildTargets m_Targets
Definition: cbproject.h:697
ProjectFile * GetTopProjectFile()
bool FileUpgraded()
Definition: projectloader.h:67
void DebugLog(const wxString &msg, Logger::level lv=Logger::info)
Definition: logmanager.h:146
virtual const CompilerSwitches & GetSwitches() const
Get the compiler&#39;s generic switches.
Definition: compiler.h:301
bool ProcessEvent(CodeBlocksEvent &event)
Definition: manager.cpp:246
wxString virtual_path
A string that represents the virtual folder this file will appear in.
Definition: projectfile.h:195
wxString GetCommonTopLevelPath() const
Definition: cbproject.cpp:423
bool GetModified() const override
Definition: cbproject.cpp:162
void SetExt(const wxString &ext)
ProjectFileArray m_FileArray
Definition: cbproject.h:707
size_t Add(const wxString &str, size_t copies=1)
bool HasVirtualBuildTarget(const wxString &alias) const
Does a virtual build target exist?
Definition: cbproject.cpp:1470
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
void SetTitle(const wxString &title) override
Changes project title.
Definition: cbproject.cpp:1650
Represents a Code::Blocks project build target.
wxString m_DefaultExecuteTarget
Definition: cbproject.h:700
bool Normalize(int flags=wxPATH_NORM_ALL, const wxString &cwd=wxEmptyString, wxPathFormat format=wxPATH_NATIVE)
void SetExtendedObjectNamesGeneration(bool ext)
Sets object names generation to extended/normal mode.
Definition: cbproject.cpp:1565
size_t GetCount() const
virtual TiXmlNode * GetExtensionsNode()
Access the <Extensions> XML node of this project.
Definition: cbproject.cpp:1659
ProjectFile * AutoGeneratedBy() const
If this is an auto-generated file, which file is generating it?
Definition: projectfile.h:201
bool RemoveVirtualBuildTarget(const wxString &alias)
Remove a virtual build target.
Definition: cbproject.cpp:1475
int wxEventType
wxUniChar GetChar(size_t n) const
ProjectsArray * GetProjects()
Retrieve an array of all the opened projects.
void SetNotes(const wxString &notes)
Set notes on the project.
Definition: cbproject.cpp:1591
wxString m_ActiveTarget
Definition: cbproject.h:698
wxString cbMergeLibPaths(const wxString &oldPath, const wxString &newPath)
Merges to LD_LIBRARY_PATH/PATH strings together to form a new valid string.
Definition: cbproject.cpp:1777
ProjectBuildTarget * AddBuildTarget(const wxString &targetName)
Add a new build target.
Definition: cbproject.cpp:1150
EVTIMPORT const wxEventType cbEVT_BUILDTARGET_ADDED
Definition: sdk_events.cpp:116
bool DirExists() const
bool FileExists() const
void RemoveAt(size_t nIndex, size_t count=1)
void AddBuildTarget(const wxString &targetName)
Make this file belong to an additional build target.
Definition: projectfile.cpp:78
wxDateTime m_LastModified
Definition: cbproject.h:725
void SetFileState(FileVisualState state)
Set the visual state (modified, read-only, etc).
int Printf(const wxString &pszFormat,...)
void SetName(const wxString &name)
bool Save()
Save the project.
Definition: cbproject.cpp:482
wxDateTime GetModificationTime() const
wxString GetFullPath(wxPathFormat format=wxPATH_NATIVE) const
int SelectTarget(int initial=-1, bool evenIfOne=false)
Displays a target selection dialog.
Definition: cbproject.cpp:1130
bool m_Loaded
Definition: cbproject.h:710
virtual bool GetModified() const
#define NULL
Definition: prefix.cpp:59
bool RemoveBuildTarget(int index)
Remove a build target.
Definition: cbproject.cpp:1284
wxArrayString m_IncludeDirs
const DLLIMPORT wxString RESOURCE_EXT
cbProject(const wxString &filename=wxEmptyString)
Constructor.
Definition: cbproject.cpp:55
static wxString Format(const wxString &format,...)
wxString Mid(size_t first, size_t nCount=wxString::npos) const
bool GetModified() const override
Returns true if editor is modified, false otherwise.
Definition: cbeditor.cpp:856
void SetMakefileExecutionDir(const wxString &dir)
Allow the specification of specific execution directory if the project use a custom Makefile...
Definition: cbproject.cpp:1004
bool Save(const wxString &filename)
bool SetActiveBuildTarget(const wxString &name)
Set the active build target.
Definition: cbproject.cpp:1355
DLLIMPORT int cbMessageBox(const wxString &message, const wxString &caption=wxEmptyString, int style=wxOK, wxWindow *parent=NULL, int x=-1, int y=-1)
wxMessageBox wrapper.
Definition: globals.cpp:1395
bool SaveLayout()
Save the project&#39;s layout.
Definition: cbproject.cpp:499
bool RenameBuildTarget(int index, const wxString &targetName)
Rename a build target.
Definition: cbproject.cpp:1178
void SetObjName(const wxString &name)
Set the generated object filename.
std::vector< Glob > GetGlobs() const
Retrieve the current globs from the project.
Definition: cbproject.cpp:1750
size_t GetDirCount() const
wxString GetFirstValidBuildTargetName(bool virtuals_too=true) const
Definition: cbproject.cpp:1345
bool ExportTargetAsProject(int index)
Export a target as a new project.
Definition: cbproject.cpp:1246
DLLIMPORT wxString realpath(const wxString &path)
Definition: globals.cpp:1348
virtual CompilerCommandGenerator * GetCommandGenerator(cbProject *project)
This is to be overridden, if compiler needs to alter the default command line generation.
Definition: compiler.cpp:298
wxString m_Makefile
Definition: cbproject.h:701