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
* $Id: workspaceloader.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
7
* $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/sdk/workspaceloader.cpp $
10
#include "sdk_precomp.h"
13
#include <wx/confbase.h>
14
#include <wx/fileconf.h>
16
#include <wx/string.h>
19
#include "projectmanager.h"
20
#include "logmanager.h"
21
#include "cbproject.h"
23
#include "workspaceloader.h"
28
#include "tinyxml/tinyxml.h"
29
#include "tinyxml/tinywxuni.h"
31
WorkspaceLoader::WorkspaceLoader()
36
WorkspaceLoader::~WorkspaceLoader()
41
inline ProjectManager* GetpMan() { return Manager::Get()->GetProjectManager(); }
42
inline LogManager* GetpMsg() { return Manager::Get()->GetLogManager(); }
44
bool WorkspaceLoader::Open(const wxString& filename, wxString& Title)
47
if (!TinyXML::LoadDocument(filename, &doc))
50
// ProjectManager* pMan = Manager::Get()->GetProjectManager();
51
// LogManager* pMsg = Manager::Get()->GetLogManager();
53
if (!GetpMan() || !GetpMsg())
56
// BUG: Race condition. to be fixed by Rick.
57
// If I click close AFTER pMan and pMsg are calculated,
59
// I modified classes projectmanager and logmanager,
60
// so that when self==NULL, they do nothing
61
// (constructors, destructors and static functions excempted from this)
62
// This way, we'll use the *manager::Get() functions to check for nulls.
64
TiXmlElement* root = doc.FirstChildElement("CodeBlocks_workspace_file");
68
root = doc.FirstChildElement("Code::Blocks_workspace_file");
71
GetpMsg()->DebugLog(_T("Not a valid Code::Blocks workspace file..."));
75
TiXmlElement* wksp = root->FirstChildElement("Workspace");
78
GetpMsg()->DebugLog(_T("No 'Workspace' element in file..."));
82
Title = cbC2U(wksp->Attribute("title")); // Conversion to unicode is automatic (see wxString::operator= )
84
TiXmlElement* proj = wksp->FirstChildElement("Project");
87
GetpMsg()->DebugLog(_T("Workspace file contains no projects..."));
91
// first loop to load projects
94
if(Manager::isappShuttingDown() || !GetpMan() || !GetpMsg())
96
wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename")));
97
if (projectFilename.IsEmpty())
99
GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?"));
103
wxFileName fname(projectFilename);
104
wxFileName wfname(filename);
105
fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
107
int ret = proj->QueryIntAttribute("active", &active);
113
cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), true); // activate it
116
cbMessageBox(_("Unable to open ") + projectFilename,
117
_("Opening WorkSpace") + filename, wxICON_WARNING);
121
case TIXML_WRONG_TYPE:
122
GetpMsg()->DebugLog(F(_T("Error %s: %s"), doc.Value(), doc.ErrorDesc()));
123
GetpMsg()->DebugLog(_T("Wrong attribute type (expected 'int')"));
126
cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), false); // don't activate it
129
cbMessageBox(_("Unable to open ") + projectFilename,
130
_("Opening WorkSpace") + filename, wxICON_WARNING);
135
proj = proj->NextSiblingElement("Project");
138
// second loop to setup dependencies
139
proj = wksp->FirstChildElement("Project");
142
cbProject* thisprj = 0;
143
wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename")));
144
if (projectFilename.IsEmpty())
146
GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?"));
151
wxFileName fname(projectFilename);
152
wxFileName wfname(filename);
153
fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
154
thisprj = Manager::Get()->GetProjectManager()->IsOpen(fname.GetFullPath());
159
TiXmlElement* dep = proj->FirstChildElement("Depends");
162
wxFileName fname(UnixFilename(cbC2U(dep->Attribute("filename"))));
163
wxFileName wfname(filename);
164
fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
165
cbProject* depprj = Manager::Get()->GetProjectManager()->IsOpen(fname.GetFullPath());
167
Manager::Get()->GetProjectManager()->AddProjectDependency(thisprj, depprj);
168
dep = dep->NextSiblingElement("Depends");
171
proj = proj->NextSiblingElement("Project");
177
bool WorkspaceLoader::Save(const wxString& title, const wxString& filename)
179
const char* ROOT_TAG = "CodeBlocks_workspace_file";
182
doc.SetCondenseWhiteSpace(false);
183
doc.InsertEndChild(TiXmlDeclaration("1.0", "UTF-8", "yes"));
184
TiXmlElement* rootnode = static_cast<TiXmlElement*>(doc.InsertEndChild(TiXmlElement(ROOT_TAG)));
188
TiXmlElement* wksp = static_cast<TiXmlElement*>(rootnode->InsertEndChild(TiXmlElement("Workspace")));
189
wksp->SetAttribute("title", cbU2C(title));
191
ProjectsArray* arr = Manager::Get()->GetProjectManager()->GetProjects();
192
for (unsigned int i = 0; i < arr->GetCount(); ++i)
194
cbProject* prj = arr->Item(i);
196
wxFileName wfname(filename);
197
wxFileName fname(prj->GetFilename());
198
fname.MakeRelativeTo(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
200
TiXmlElement* node = static_cast<TiXmlElement*>(wksp->InsertEndChild(TiXmlElement("Project")));
201
node->SetAttribute("filename", cbU2C(fname.GetFullPath()));
202
if (prj == Manager::Get()->GetProjectManager()->GetActiveProject())
203
node->SetAttribute("active", 1);
205
const ProjectsArray* deps = Manager::Get()->GetProjectManager()->GetDependenciesForProject(prj);
206
if (deps && deps->GetCount())
208
for (size_t i = 0; i < deps->GetCount(); ++i)
211
fname.Assign(prj->GetFilename());
212
fname.MakeRelativeTo(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
213
TiXmlElement* dnode = static_cast<TiXmlElement*>(node->InsertEndChild(TiXmlElement("Depends")));
214
dnode->SetAttribute("filename", cbU2C(fname.GetFullPath()));
218
return cbSaveTinyXMLDocument(&doc, filename);