FreeCAD

Форк
0
/
AppTechDrawGuiPy.cpp 
465 строк · 17.8 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2016 WandererFan <wandererfan@gmail.com>                *
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

25
#include <App/Document.h>
26
#include <App/DocumentObject.h>
27
#include <App/DocumentObjectPy.h>
28
#include <Base/Console.h>
29
#include <Base/Exception.h>
30
#include <Base/FileInfo.h>
31
#include <Gui/Application.h>
32
#include <Gui/Document.h>
33
#include <Gui/ViewProvider.h>
34
#include <Gui/PythonWrapper.h>
35
#include <Mod/Part/App/OCCError.h>
36
#include <Mod/TechDraw/App/DrawPage.h>
37
#include <Mod/TechDraw/App/DrawPagePy.h>
38
#include <Mod/TechDraw/App/DrawViewPy.h>  // generated from DrawViewPy.xml
39

40
#include "MDIViewPage.h"
41
#include "QGIView.h"
42
#include "QGSPage.h"
43
#include "ViewProviderPage.h"
44
#include "ViewProviderDrawingView.h"
45
#include "PagePrinter.h"
46

47

48
namespace TechDrawGui {
49

50
class Module : public Py::ExtensionModule<Module>
51
{
52
public:
53
    Module() : Py::ExtensionModule<Module>("TechDrawGui")
54
    {
55
       add_varargs_method("export", &Module::exporter,
56
            "TechDraw hook for FC Gui exporter."
57
       );
58
       add_varargs_method("exportPageAsPdf", &Module::exportPageAsPdf,
59
            "exportPageAsPdf(DrawPageObject, FilePath) -- print page as Pdf to file."
60
        );
61
        add_varargs_method("exportPageAsSvg", &Module::exportPageAsSvg,
62
            "exportPageAsSvg(DrawPageObject, FilePath) -- print page as Svg to file."
63
        );
64
        add_varargs_method("addQGIToView", &Module::addQGIToView,
65
            "addQGIToView(View, QGraphicsItem) -- insert graphics item into view's graphic."
66
        );
67
        add_varargs_method("addQGObjToView", &Module::addQGObjToView,
68
            "addQGObjToView(View, QGraphicsObject) -- insert graphics object into view's graphic. Use for QGraphicsItems that have QGraphicsObject as base class."
69
        );
70
        add_varargs_method("addQGIToScene", &Module::addQGIToScene,
71
            "addQGIToScene(Page, QGraphicsItem) -- insert graphics item into Page's scene."
72
        );
73
        add_varargs_method("addQGObjToScene", &Module::addQGObjToScene,
74
            "addQGObjToScene(Page, QGraphicsObject) -- insert graphics object into Page's scene. Use for QGraphicsItems that have QGraphicsObject as base class."
75
        );
76
        add_varargs_method("getSceneForPage", &Module::getSceneForPage,
77
            "QGSPage = getSceneForPage(page) -- get the scene for a DrawPage."
78
        );
79
        initialize("This is a module for displaying drawings"); // register with Python
80
    }
81
    ~Module() override {}
82

83
private:
84
    Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) override
85
    {
86
        try {
87
            return Py::ExtensionModule<Module>::invoke_method_varargs(method_def, args);
88
        }
89
        catch (const Standard_Failure &e) {
90
            std::string str;
91
            Standard_CString msg = e.GetMessageString();
92
            str += typeid(e).name();
93
            str += " ";
94
            if (msg) {str += msg;}
95
            else     {str += "No OCCT Exception Message";}
96
            Base::Console().Error("%s\n", str.c_str());
97
            throw Py::Exception(Part::PartExceptionOCCError, str);
98
        }
99
        catch (const Base::Exception &e) {
100
            std::string str;
101
            str += "FreeCAD exception thrown (";
102
            str += e.what();
103
            str += ")";
104
            e.ReportException();
105
            throw Py::RuntimeError(str);
106
        }
107
        catch (const std::exception &e) {
108
            std::string str;
109
            str += "C++ exception thrown (";
110
            str += e.what();
111
            str += ")";
112
            Base::Console().Error("%s\n", str.c_str());
113
            throw Py::RuntimeError(str);
114
        }
115
        return Py::None(); //only here to prevent warning re no return value
116
    }
117

118
//! hook for FC Gui export function
119
    Py::Object exporter(const Py::Tuple& args)
120
    {
121
        PyObject* object;
122
        char* Name;
123
        if (!PyArg_ParseTuple(args.ptr(), "Oet", &object, "utf-8", &Name))
124
            throw Py::Exception();
125

126
        std::string EncodedName = std::string(Name);
127
        PyMem_Free(Name);
128

129
        TechDraw::DrawPage* page = nullptr;
130
        Py::Sequence list(object);
131
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
132
            PyObject* item = (*it).ptr();
133
            if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
134
                App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
135
                if (obj->isDerivedFrom<TechDraw::DrawPage>()) {
136
                    page = static_cast<TechDraw::DrawPage*>(obj);
137
                    Gui::Document* activeGui = Gui::Application::Instance->getDocument(page->getDocument());
138
                    Gui::ViewProvider* vp = activeGui->getViewProvider(obj);
139
                    ViewProviderPage* dvp = dynamic_cast<ViewProviderPage*>(vp);
140
                    if ( !(dvp  && dvp->getMDIViewPage()) ) {
141
                        throw Py::TypeError("TechDraw can not find Page");
142
                    }
143

144
                    Base::FileInfo fi_out(EncodedName.c_str());
145

146
                    if (fi_out.hasExtension("svg")) {
147
                        dvp->getMDIViewPage()->saveSVG(EncodedName);
148
                    } else if (fi_out.hasExtension("dxf")) {
149
                        dvp->getMDIViewPage()->saveDXF(EncodedName);
150
                    } else if (fi_out.hasExtension("pdf")) {
151
                        dvp->getMDIViewPage()->savePDF(EncodedName);
152
                    } else {
153
                        throw Py::TypeError("TechDraw can not export this file format");
154
                    }
155
                }
156
                else {
157
                    throw Py::TypeError("No Technical Drawing Page found in selection.");
158
                }
159
            }
160
        }
161

162
        return Py::None();
163
    }
164

165
//!exportPageAsPdf(PageObject, FullPath)
166
    Py::Object exportPageAsPdf(const Py::Tuple& args)
167
    {
168
        PyObject *pageObj;
169
        char* name;
170
        if (!PyArg_ParseTuple(args.ptr(), "Oet", &pageObj, "utf-8", &name)) {
171
            throw Py::TypeError("expected (Page, path");
172
        }
173

174
        std::string filePath = std::string(name);
175
        PyMem_Free(name);
176

177
        try {
178
           App::DocumentObject* obj = nullptr;
179
           Gui::ViewProvider* vp = nullptr;
180
           MDIViewPage* mdi = nullptr;
181
           if (PyObject_TypeCheck(pageObj, &(App::DocumentObjectPy::Type))) {
182
               obj = static_cast<App::DocumentObjectPy*>(pageObj)->getDocumentObjectPtr();
183
               vp = Gui::Application::Instance->getViewProvider(obj);
184
               if (vp) {
185
                   TechDrawGui::ViewProviderPage* vpp = dynamic_cast<TechDrawGui::ViewProviderPage*>(vp);
186
                   if (vpp) {
187
                       mdi = vpp->getMDIViewPage();
188
                       if (mdi) {
189
                           mdi->savePDF(filePath);
190
                       } else {
191
                           vpp->showMDIViewPage();
192
                           mdi = vpp->getMDIViewPage();
193
                           if (mdi) {
194
                               mdi->savePDF(filePath);
195
                           } else {
196
                               throw Py::TypeError("Page not available! Is it Hidden?");
197
                           }
198
                       }
199
                   }
200
               }
201
           }
202
        }
203
        catch (Base::Exception &e) {
204
            e.setPyException();
205
            throw Py::Exception();
206
        }
207

208
        return Py::None();
209
    }
210

211
//!exportPageAsSvg(PageObject, FullPath)
212
    Py::Object exportPageAsSvg(const Py::Tuple& args)
213
    {
214
        PyObject *pageObj;
215
        char* name;
216
        if (!PyArg_ParseTuple(args.ptr(), "Oet", &pageObj, "utf-8", &name)) {
217
            throw Py::TypeError("expected (Page, path");
218
        }
219

220
        std::string filePath = std::string(name);
221
        PyMem_Free(name);
222

223
        try {
224
           App::DocumentObject* obj = nullptr;
225
           Gui::ViewProvider* vp = nullptr;
226
           MDIViewPage* mdi = nullptr;
227
           if (PyObject_TypeCheck(pageObj, &(App::DocumentObjectPy::Type))) {
228
               obj = static_cast<App::DocumentObjectPy*>(pageObj)->getDocumentObjectPtr();
229
               vp = Gui::Application::Instance->getViewProvider(obj);
230
               if (vp) {
231
                   TechDrawGui::ViewProviderPage* vpp = dynamic_cast<TechDrawGui::ViewProviderPage*>(vp);
232
                   if (vpp) {
233
                       mdi = vpp->getMDIViewPage();
234
                       if (mdi) {
235
                           mdi->saveSVG(filePath);
236
                       } else {
237
                           vpp->showMDIViewPage();
238
                           mdi = vpp->getMDIViewPage();
239
                           if (mdi) {
240
                               mdi->saveSVG(filePath);
241
                           } else {
242
                               throw Py::TypeError("Page not available! Is it Hidden?");
243
                           }
244
                       }
245
                   }
246
               }
247
           }
248
        }
249
        catch (Base::Exception &e) {
250
            e.setPyException();
251
            throw Py::Exception();
252
        }
253

254
        return Py::None();
255
    }
256

257
        Py::Object addQGIToView(const Py::Tuple& args)
258
    {
259
        PyObject *viewPy = nullptr;
260
        PyObject *qgiPy = nullptr;
261
        if (!PyArg_ParseTuple(args.ptr(), "O!O", &(TechDraw::DrawViewPy::Type), &viewPy, &qgiPy)) {
262
            throw Py::TypeError("expected (view, item)");
263
        }
264

265
        try {
266
           App::DocumentObject* obj = nullptr;
267
           Gui::ViewProvider* vp = nullptr;
268
           QGIView* qgiv = nullptr;
269
           obj = static_cast<App::DocumentObjectPy*>(viewPy)->getDocumentObjectPtr();
270
           vp = Gui::Application::Instance->getViewProvider(obj);
271
           if (vp) {
272
               TechDrawGui::ViewProviderDrawingView* vpdv =
273
                            dynamic_cast<TechDrawGui::ViewProviderDrawingView*>(vp);
274
               if (vpdv) {
275
                   qgiv = vpdv->getQView();
276
                   if (qgiv) {
277
                       Gui::PythonWrapper wrap;
278
                       if (!wrap.loadGuiModule()) {
279
                           throw Py::RuntimeError("Failed to load Python wrapper for Qt::Gui");
280
                        }
281
                        QGraphicsItem* item = wrap.toQGraphicsItem(args[1]);
282
                        if (item) {
283
                            qgiv->addArbitraryItem(item);
284
                        }
285
                    }
286
               }
287
           }
288
        }
289
        catch (Base::Exception &e) {
290
            e.setPyException();
291
            throw Py::Exception();
292
        }
293

294
        return Py::None();
295
    }
296

297
    Py::Object addQGObjToView(const Py::Tuple& args)
298
    {
299
        PyObject *viewPy = nullptr;
300
        PyObject *qgiPy = nullptr;
301
        if (!PyArg_ParseTuple(args.ptr(), "O!O", &(TechDraw::DrawViewPy::Type), &viewPy, &qgiPy)) {
302
            throw Py::TypeError("expected (view, item)");
303
        }
304

305
        try {
306
           App::DocumentObject* obj = nullptr;
307
           Gui::ViewProvider* vp = nullptr;
308
           QGIView* qgiv = nullptr;
309
           obj = static_cast<App::DocumentObjectPy*>(viewPy)->getDocumentObjectPtr();
310
           vp = Gui::Application::Instance->getViewProvider(obj);
311
           if (vp) {
312
               TechDrawGui::ViewProviderDrawingView* vpdv =
313
                            dynamic_cast<TechDrawGui::ViewProviderDrawingView*>(vp);
314
               if (vpdv) {
315
                   qgiv = vpdv->getQView();
316
                   if (qgiv) {
317
                       Gui::PythonWrapper wrap;
318
                       if (!wrap.loadGuiModule()) {
319
                           throw Py::RuntimeError("Failed to load Python wrapper for Qt::Gui");
320
                        }
321
                        QGraphicsObject* item = wrap.toQGraphicsObject(args[1]);
322
                        if (item) {
323
                            qgiv->addArbitraryItem(item);
324
                        }
325
                    }
326
               }
327
           }
328
        }
329
        catch (Base::Exception &e) {
330
            e.setPyException();
331
            throw Py::Exception();
332
        }
333

334
        return Py::None();
335
    }
336

337

338
    //adds a free graphics item to a Page's scene
339
    Py::Object addQGIToScene(const Py::Tuple& args)
340
    {
341
        PyObject *pagePy = nullptr;
342
        PyObject *qgiPy = nullptr;
343
        if (!PyArg_ParseTuple(args.ptr(), "O!O", &(TechDraw::DrawPagePy::Type), &pagePy, &qgiPy)) {
344
            throw Py::TypeError("expected (view, item)");
345
        }
346

347
        try {
348
           App::DocumentObject* obj = nullptr;
349
           Gui::ViewProvider* vp = nullptr;
350
           QGSPage* qgsp = nullptr;
351
           obj = static_cast<App::DocumentObjectPy*>(pagePy)->getDocumentObjectPtr();
352
           vp = Gui::Application::Instance->getViewProvider(obj);
353
           if (vp) {
354
               TechDrawGui::ViewProviderPage* vpp =
355
                            dynamic_cast<TechDrawGui::ViewProviderPage*>(vp);
356
               if (vpp) {
357
                   qgsp = vpp->getQGSPage();
358
                   if (qgsp) {
359
                       Gui::PythonWrapper wrap;
360
                       if (!wrap.loadGuiModule()) {
361
                           throw Py::RuntimeError("Failed to load Python wrapper for Qt::Gui");
362
                       }
363
                        QGraphicsItem* item = wrap.toQGraphicsItem(args[1]);
364
                        if (item) {
365
                            qgsp->addItem(item);
366
                        }
367
                    }
368
               }
369
           }
370
        }
371
        catch (Base::Exception &e) {
372
            e.setPyException();
373
            throw Py::Exception();
374
        }
375

376
        return Py::None();
377
    }
378

379

380
    //adds a free graphics object to a Page's scene
381
//!use addQGObjToScene for QGraphics items like QGraphicsSvgItem or QGraphicsTextItem that are
382
//! derived from QGraphicsObject
383
    Py::Object addQGObjToScene(const Py::Tuple& args)
384
    {
385
        PyObject *pagePy = nullptr;
386
        PyObject *qgiPy = nullptr;
387
        if (!PyArg_ParseTuple(args.ptr(), "O!O", &(TechDraw::DrawPagePy::Type), &pagePy, &qgiPy)) {
388
            throw Py::TypeError("expected (view, item)");
389
        }
390

391
        try {
392
           App::DocumentObject* obj = nullptr;
393
           Gui::ViewProvider* vp = nullptr;
394
           QGSPage* qgsp = nullptr;
395
           obj = static_cast<App::DocumentObjectPy*>(pagePy)->getDocumentObjectPtr();
396
           vp = Gui::Application::Instance->getViewProvider(obj);
397
           if (vp) {
398
               TechDrawGui::ViewProviderPage* vpp =
399
                            dynamic_cast<TechDrawGui::ViewProviderPage*>(vp);
400
               if (vpp) {
401
                   qgsp = vpp->getQGSPage();
402
                   if (qgsp) {
403
                       Gui::PythonWrapper wrap;
404
                       if (!wrap.loadGuiModule()) {
405
                           throw Py::RuntimeError("Failed to load Python wrapper for Qt::Gui");
406
                       }
407
                        QGraphicsObject* item = wrap.toQGraphicsObject(args[1]);
408
                        if (item) {
409
                            qgsp->addItem(item);
410
                        }
411
                    }
412
               }
413
           }
414
        }
415
        catch (Base::Exception &e) {
416
            e.setPyException();
417
            throw Py::Exception();
418
        }
419

420
        return Py::None();
421
    }
422

423
    Py::Object getSceneForPage(const Py::Tuple& args)
424
    {
425
        PyObject *pagePy = nullptr;
426
        if (!PyArg_ParseTuple(args.ptr(), "O!", &(TechDraw::DrawPagePy::Type), &pagePy)) {
427
            throw Py::TypeError("expected (page)");
428
        }
429

430
        try {
431
           App::DocumentObject* obj = nullptr;
432
           Gui::ViewProvider* vp = nullptr;
433
           QGSPage* qgsp = nullptr;
434
           obj = static_cast<App::DocumentObjectPy*>(pagePy)->getDocumentObjectPtr();
435
           vp = Gui::Application::Instance->getViewProvider(obj);
436
           if (vp) {
437
               TechDrawGui::ViewProviderPage* vpp =
438
                            dynamic_cast<TechDrawGui::ViewProviderPage*>(vp);
439
               if (vpp) {
440
                   qgsp = vpp->getQGSPage();
441
                   if (qgsp) {
442
                       Gui::PythonWrapper wrap;
443
                       if (!wrap.loadGuiModule()) {
444
                           throw Py::RuntimeError("Failed to load Python wrapper for Qt::Gui");
445
                       }
446
                       return wrap.fromQObject(qgsp, "TechDrawGui::QGSPage");
447
                    }
448
               }
449
           }
450
        }
451
        catch (Base::Exception &e) {
452
            e.setPyException();
453
            throw Py::Exception();
454
        }
455

456
        return Py::None();
457
    }
458
};
459

460
PyObject* initModule()
461
{
462
    return Base::Interpreter().addModule(new Module);
463
}
464

465
} // namespace TechDrawGui
466

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

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

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

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