FreeCAD

Форк
0
/
FeaturePage.cpp 
304 строки · 11.5 Кб
1
/***************************************************************************
2
 *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
#include <fstream>
26
#include <iostream>
27
#include <iterator>
28
#include <sstream>
29

30
#include <boost/regex.hpp>
31
#endif
32

33
#include <App/Application.h>
34
#include <Base/Console.h>
35
#include <Base/FileInfo.h>
36

37
#include "FeatureClip.h"
38
#include "FeaturePage.h"
39
#include "FeatureView.h"
40

41

42
using namespace Drawing;
43
using namespace std;
44

45
//===========================================================================
46
// FeaturePage
47
//===========================================================================
48

49
PROPERTY_SOURCE(Drawing::FeaturePage, App::DocumentObjectGroup)
50

51
FeaturePage::FeaturePage(void)
52
    : numChildren(0)
53
{
54
    static const char* group = "Drawing view";
55

56
    ADD_PROPERTY_TYPE(PageResult,
57
                      (nullptr),
58
                      group,
59
                      App::Prop_Output,
60
                      "Resulting SVG document of that page");
61
    ADD_PROPERTY_TYPE(Template, (""), group, App::Prop_None, "Template for the page");
62
    ADD_PROPERTY_TYPE(EditableTexts,
63
                      (""),
64
                      group,
65
                      App::Prop_None,
66
                      "Substitution values for the editable strings in the template");
67
}
68

69
FeaturePage::~FeaturePage()
70
{}
71

72
void FeaturePage::onBeforeChange(const App::Property* prop)
73
{
74
    if (prop == &Group) {
75
        numChildren = Group.getSize();
76
    }
77

78
    App::DocumentObjectGroup::onBeforeChange(prop);
79
}
80

81
/// get called by the container when a Property was changed
82
void FeaturePage::onChanged(const App::Property* prop)
83
{
84
    if (prop == &PageResult) {
85
        if (this->isRestoring()) {
86
            // When loading a document the included file
87
            // doesn't need to exist at this point.
88
            Base::FileInfo fi(PageResult.getValue());
89
            if (!fi.exists()) {
90
                return;
91
            }
92
        }
93
    }
94
    else if (prop == &EditableTexts) {
95
        if (!this->isRestoring()) {
96
            this->execute();
97
            return;
98
        }
99
    }
100
    else if (prop == &Template) {
101
        if (!this->isRestoring()) {
102
            EditableTexts.setValues(getEditableTextsFromTemplate());
103
        }
104
    }
105
    else if (prop == &Group) {
106
        if (Group.getSize() != numChildren) {
107
            numChildren = Group.getSize();
108
            touch();
109
        }
110
    }
111

112
    App::DocumentObjectGroup::onChanged(prop);
113
}
114

115
void FeaturePage::onDocumentRestored()
116
{
117
    // Needs to be tmp. set because otherwise the custom text gets overridden (#0002064)
118
    this->StatusBits.set(App::Restore);  // the 'Restore' flag
119

120
    Base::FileInfo templateInfo(Template.getValue());
121
    if (!templateInfo.exists()) {
122
        Base::FileInfo fi(Template.getValue());
123
        if (fi.fileName().empty()) {
124
            fi.setFile(PageResult.getValue());
125
        }
126
        std::string path =
127
            App::Application::getResourceDir() + "Mod/Drawing/Templates/" + fi.fileName();
128
        // try to find the template in user dir/Templates first
129
        Base::FileInfo tempfi(App::Application::getUserAppDataDir() + "Templates/" + fi.fileName());
130
        if (tempfi.exists()) {
131
            path = tempfi.filePath();
132
        }
133
        Template.setValue(path);
134
    }
135

136
    this->StatusBits.reset(App::Restore);  // the 'Restore' flag
137
}
138

139
App::DocumentObjectExecReturn* FeaturePage::execute(void)
140
{
141
    std::string temp = Template.getValue();
142
    if (temp.empty()) {
143
        return App::DocumentObject::StdReturn;
144
    }
145

146
    Base::FileInfo fi(temp);
147
    if (!fi.isReadable()) {
148
        // if there is a old absolute template file set use a redirect
149
        fi.setFile(App::Application::getResourceDir() + "Mod/Drawing/Templates/" + fi.fileName());
150
        // try the redirect
151
        if (!fi.isReadable()) {
152
            Base::Console().Log("FeaturePage::execute() not able to open %s!\n",
153
                                Template.getValue());
154
            std::string error = std::string("Cannot open file ") + Template.getValue();
155
            return new App::DocumentObjectExecReturn(error);
156
        }
157
    }
158

159
    if (std::string(PageResult.getValue()).empty()) {
160
        PageResult.setValue(fi.filePath().c_str());
161
    }
162

163
    // open Template file
164
    string line;
165
    ifstream file(fi.filePath().c_str());
166

167
    // make a temp file for FileIncluded Property
168
    string tempName = PageResult.getExchangeTempFile();
169
    ostringstream ofile;
170
    string tempendl = "--endOfLine--";
171

172
    while (getline(file, line)) {
173
        // check if the marker in the template is found
174
        if (line.find("<!-- DrawingContent -->") == string::npos) {
175
            // if not -  write through
176
            ofile << line << tempendl;
177
        }
178
        else {
179
            // get through the children and collect all the views
180
            const std::vector<App::DocumentObject*>& Grp = Group.getValues();
181
            for (std::vector<App::DocumentObject*>::const_iterator It = Grp.begin();
182
                 It != Grp.end();
183
                 ++It) {
184
                if ((*It)->isDerivedFrom<Drawing::FeatureView>()) {
185
                    Drawing::FeatureView* View = static_cast<Drawing::FeatureView*>(*It);
186
                    if (View->Visible.getValue()) {
187
                        ofile << View->ViewResult.getValue();
188
                        ofile << tempendl << tempendl << tempendl;
189
                    }
190
                }
191
                else if ((*It)->isDerivedFrom<Drawing::FeatureClip>()) {
192
                    Drawing::FeatureClip* Clip = static_cast<Drawing::FeatureClip*>(*It);
193
                    if (Clip->Visible.getValue()) {
194
                        ofile << Clip->ViewResult.getValue();
195
                        ofile << tempendl << tempendl << tempendl;
196
                    }
197
                }
198
                else if ((*It)->isDerivedFrom<App::DocumentObjectGroup>()) {
199
                    // getting children inside subgroups too
200
                    App::DocumentObjectGroup* SubGroup =
201
                        static_cast<App::DocumentObjectGroup*>(*It);
202
                    const std::vector<App::DocumentObject*>& SubGrp = SubGroup->Group.getValues();
203
                    for (std::vector<App::DocumentObject*>::const_iterator Grit = SubGrp.begin();
204
                         Grit != SubGrp.end();
205
                         ++Grit) {
206
                        if ((*Grit)->isDerivedFrom<Drawing::FeatureView>()) {
207
                            Drawing::FeatureView* SView = static_cast<Drawing::FeatureView*>(*Grit);
208
                            if (SView->Visible.getValue()) {
209
                                ofile << SView->ViewResult.getValue();
210
                                ofile << tempendl << tempendl << tempendl;
211
                            }
212
                        }
213
                    }
214
                }
215
            }
216
        }
217
    }
218

219
    file.close();
220

221
    // checking for freecad editable texts
222
    string outfragment(ofile.str());
223
    const std::vector<std::string>& editText = EditableTexts.getValues();
224
    if (!editText.empty()) {
225
        boost::regex e1("<text.*?freecad:editable=\"(.*?)\".*?<tspan.*?>(.*?)</tspan>");
226
        string::const_iterator begin, end;
227
        begin = outfragment.begin();
228
        end = outfragment.end();
229
        boost::match_results<std::string::const_iterator> what;
230
        std::size_t count = 0;
231
        std::string newfragment;
232
        newfragment.reserve(outfragment.size());
233

234
        while (boost::regex_search(begin, end, what, e1)) {
235
            if (count < editText.size()) {
236
                // change values of editable texts
237
                boost::regex e2("(<text.*?freecad:editable=\"" + what[1].str()
238
                                + "\".*?<tspan.*?)>(.*?)(</tspan>)");
239
                std::back_insert_iterator<std::string> out(newfragment);
240
                boost::regex_replace(out,
241
                                     begin,
242
                                     what[0].second,
243
                                     e2,
244
                                     "$1>" + editText[count] + "$3");
245
            }
246
            count++;
247
            begin = what[0].second;
248
        }
249

250
        // now copy the rest
251
        newfragment.insert(newfragment.end(), begin, end);
252
        outfragment = newfragment;
253
    }
254

255
    // restoring linebreaks and saving the file
256
    boost::regex e3("--endOfLine--");
257
    string fmt = "\\n";
258
    outfragment = boost::regex_replace(outfragment, e3, fmt);
259
    ofstream outfinal(tempName.c_str());
260
    outfinal << outfragment;
261
    outfinal.close();
262

263
    PageResult.setValue(tempName.c_str());
264

265
    return App::DocumentObject::StdReturn;
266
}
267

268
std::vector<std::string> FeaturePage::getEditableTextsFromTemplate(void) const
269
{
270
    // getting editable texts from "freecad:editable" attributes in SVG template
271

272
    std::vector<string> eds;
273

274
    std::string temp = Template.getValue();
275
    if (!temp.empty()) {
276
        Base::FileInfo tfi(temp);
277
        if (!tfi.isReadable()) {
278
            // if there is a old absolute template file set use a redirect
279
            tfi.setFile(App::Application::getResourceDir() + "Mod/Drawing/Templates/"
280
                        + tfi.fileName());
281
            // try the redirect
282
            if (!tfi.isReadable()) {
283
                return eds;
284
            }
285
        }
286
        string tline, tfrag;
287
        ifstream tfile(tfi.filePath().c_str());
288
        while (getline(tfile, tline)) {
289
            tfrag += tline;
290
            tfrag += "--endOfLine--";
291
        }
292
        tfile.close();
293
        boost::regex e("<text.*?freecad:editable=\"(.*?)\".*?<tspan.*?>(.*?)</tspan>");
294
        string::const_iterator tbegin, tend;
295
        tbegin = tfrag.begin();
296
        tend = tfrag.end();
297
        boost::match_results<std::string::const_iterator> twhat;
298
        while (boost::regex_search(tbegin, tend, twhat, e)) {
299
            eds.push_back(twhat[2]);
300
            tbegin = twhat[0].second;
301
        }
302
    }
303
    return eds;
304
}
305

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.