~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/sdk/workspaceloader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: 4909 $
 
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 $
 
8
 */
 
9
 
 
10
#include "sdk_precomp.h"
 
11
 
 
12
#ifndef CB_PRECOMP
 
13
    #include <wx/confbase.h>
 
14
    #include <wx/fileconf.h>
 
15
    #include <wx/intl.h>
 
16
    #include <wx/string.h>
 
17
 
 
18
    #include "manager.h"
 
19
    #include "projectmanager.h"
 
20
    #include "logmanager.h"
 
21
    #include "cbproject.h"
 
22
    #include "globals.h"
 
23
    #include "workspaceloader.h"
 
24
#endif
 
25
 
 
26
 
 
27
 
 
28
#include "tinyxml/tinyxml.h"
 
29
#include "tinyxml/tinywxuni.h"
 
30
 
 
31
WorkspaceLoader::WorkspaceLoader()
 
32
{
 
33
        //ctor
 
34
}
 
35
 
 
36
WorkspaceLoader::~WorkspaceLoader()
 
37
{
 
38
        //dtor
 
39
}
 
40
 
 
41
inline ProjectManager* GetpMan() { return Manager::Get()->GetProjectManager(); }
 
42
inline LogManager* GetpMsg() { return Manager::Get()->GetLogManager(); }
 
43
 
 
44
bool WorkspaceLoader::Open(const wxString& filename, wxString& Title)
 
45
{
 
46
    TiXmlDocument doc;
 
47
    if (!TinyXML::LoadDocument(filename, &doc))
 
48
        return false;
 
49
 
 
50
//    ProjectManager* pMan = Manager::Get()->GetProjectManager();
 
51
//    LogManager* pMsg = Manager::Get()->GetLogManager();
 
52
 
 
53
    if (!GetpMan() || !GetpMsg())
 
54
        return false;
 
55
 
 
56
    // BUG: Race condition. to be fixed by Rick.
 
57
    // If I click close AFTER pMan and pMsg are calculated,
 
58
    // I get a segfault.
 
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.
 
63
 
 
64
    TiXmlElement* root = doc.FirstChildElement("CodeBlocks_workspace_file");
 
65
    if (!root)
 
66
    {
 
67
        // old tag
 
68
        root = doc.FirstChildElement("Code::Blocks_workspace_file");
 
69
        if (!root)
 
70
        {
 
71
            GetpMsg()->DebugLog(_T("Not a valid Code::Blocks workspace file..."));
 
72
            return false;
 
73
        }
 
74
    }
 
75
    TiXmlElement* wksp = root->FirstChildElement("Workspace");
 
76
    if (!wksp)
 
77
    {
 
78
        GetpMsg()->DebugLog(_T("No 'Workspace' element in file..."));
 
79
        return false;
 
80
    }
 
81
 
 
82
    Title = cbC2U(wksp->Attribute("title")); // Conversion to unicode is automatic (see wxString::operator= )
 
83
 
 
84
    TiXmlElement* proj = wksp->FirstChildElement("Project");
 
85
    if (!proj)
 
86
    {
 
87
        GetpMsg()->DebugLog(_T("Workspace file contains no projects..."));
 
88
        return false;
 
89
    }
 
90
 
 
91
    // first loop to load projects
 
92
    while (proj)
 
93
    {
 
94
        if(Manager::isappShuttingDown() || !GetpMan() || !GetpMsg())
 
95
            return false;
 
96
        wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename")));
 
97
        if (projectFilename.IsEmpty())
 
98
        {
 
99
            GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?"));
 
100
        }
 
101
        else
 
102
        {
 
103
            wxFileName fname(projectFilename);
 
104
            wxFileName wfname(filename);
 
105
            fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
 
106
            int active = 0;
 
107
            int ret = proj->QueryIntAttribute("active", &active);
 
108
            switch (ret)
 
109
            {
 
110
                case TIXML_SUCCESS:
 
111
                    if (active == 1)
 
112
                                        {
 
113
                                                cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), true); // activate it
 
114
                                                if(!pProject)
 
115
                                                {
 
116
                                                        cbMessageBox(_("Unable to open ") + projectFilename,
 
117
                                                         _("Opening WorkSpace") + filename, wxICON_WARNING);
 
118
                                                }
 
119
                                        }
 
120
                    break;
 
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')"));
 
124
                    break;
 
125
                default:
 
126
                                        cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), false); // don't activate it
 
127
                                        if(!pProject)
 
128
                                        {
 
129
                                                cbMessageBox(_("Unable to open ") + projectFilename,
 
130
                                                 _("Opening WorkSpace") + filename, wxICON_WARNING);
 
131
                                        }
 
132
                    break;
 
133
            }
 
134
        }
 
135
        proj = proj->NextSiblingElement("Project");
 
136
    }
 
137
 
 
138
    // second loop to setup dependencies
 
139
    proj = wksp->FirstChildElement("Project");
 
140
    while (proj)
 
141
    {
 
142
        cbProject* thisprj = 0;
 
143
        wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename")));
 
144
        if (projectFilename.IsEmpty())
 
145
        {
 
146
            GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?"));
 
147
            thisprj = 0;
 
148
        }
 
149
        else
 
150
        {
 
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());
 
155
        }
 
156
 
 
157
        if (thisprj)
 
158
        {
 
159
            TiXmlElement* dep = proj->FirstChildElement("Depends");
 
160
            while (dep)
 
161
            {
 
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());
 
166
                if (depprj)
 
167
                    Manager::Get()->GetProjectManager()->AddProjectDependency(thisprj, depprj);
 
168
                dep = dep->NextSiblingElement("Depends");
 
169
            }
 
170
        }
 
171
        proj = proj->NextSiblingElement("Project");
 
172
    }
 
173
 
 
174
    return true;
 
175
}
 
176
 
 
177
bool WorkspaceLoader::Save(const wxString& title, const wxString& filename)
 
178
{
 
179
    const char* ROOT_TAG = "CodeBlocks_workspace_file";
 
180
 
 
181
    TiXmlDocument doc;
 
182
    doc.SetCondenseWhiteSpace(false);
 
183
    doc.InsertEndChild(TiXmlDeclaration("1.0", "UTF-8", "yes"));
 
184
    TiXmlElement* rootnode = static_cast<TiXmlElement*>(doc.InsertEndChild(TiXmlElement(ROOT_TAG)));
 
185
    if (!rootnode)
 
186
        return false;
 
187
 
 
188
    TiXmlElement* wksp = static_cast<TiXmlElement*>(rootnode->InsertEndChild(TiXmlElement("Workspace")));
 
189
    wksp->SetAttribute("title", cbU2C(title));
 
190
 
 
191
    ProjectsArray* arr = Manager::Get()->GetProjectManager()->GetProjects();
 
192
    for (unsigned int i = 0; i < arr->GetCount(); ++i)
 
193
    {
 
194
        cbProject* prj = arr->Item(i);
 
195
 
 
196
        wxFileName wfname(filename);
 
197
        wxFileName fname(prj->GetFilename());
 
198
        fname.MakeRelativeTo(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
 
199
 
 
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);
 
204
 
 
205
        const ProjectsArray* deps = Manager::Get()->GetProjectManager()->GetDependenciesForProject(prj);
 
206
        if (deps && deps->GetCount())
 
207
        {
 
208
            for (size_t i = 0; i < deps->GetCount(); ++i)
 
209
            {
 
210
                prj = deps->Item(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()));
 
215
            }
 
216
        }
 
217
    }
 
218
    return cbSaveTinyXMLDocument(&doc, filename);
 
219
}