FreeCAD

Форк
0
/
DocumentPyImp.cpp 
573 строки · 16.9 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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
#ifndef _PreComp_
26
# include <sstream>
27
#endif
28

29
#include <App/Document.h>
30
#include <Base/Matrix.h>
31
#include <Base/MatrixPy.h>
32
#include <Base/Stream.h>
33

34
#include "Application.h"
35
#include "MergeDocuments.h"
36
#include "MDIView.h"
37
#include "ViewProviderExtern.h"
38

39
// inclusion of the generated files (generated out of DocumentPy.xml)
40
#include "DocumentPy.h"
41
#include "DocumentPy.cpp"
42
#include <App/DocumentObjectPy.h>
43
#include "Tree.h"
44
#include "ViewProviderDocumentObject.h"
45
#include "ViewProviderDocumentObjectPy.h"
46
#include "ViewProviderPy.h"
47
#include "ViewProviderDocumentObjectPy.h"
48

49

50
using namespace Gui;
51

52
// returns a string which represent the object e.g. when printed in python
53
std::string DocumentPy::representation() const
54
{
55
    std::stringstream str;
56
    str << "<GUI Document object at " << getDocumentPtr() << ">";
57

58
    return str.str();
59
}
60

61

62
PyObject* DocumentPy::show(PyObject *args)
63
{
64
    char *psFeatStr;
65
    if (!PyArg_ParseTuple(args, "s;Name of the Feature to show have to be given!", &psFeatStr))
66
        return nullptr;
67

68
    PY_TRY {
69
        getDocumentPtr()->setShow(psFeatStr);
70
        Py_Return;
71
    }
72
    PY_CATCH;
73
}
74

75
PyObject* DocumentPy::hide(PyObject *args)
76
{
77
    char *psFeatStr;
78
    if (!PyArg_ParseTuple(args, "s;Name of the Feature to hide have to be given!", &psFeatStr))
79
        return nullptr;
80

81
    PY_TRY {
82
        getDocumentPtr()->setHide(psFeatStr);
83
        Py_Return;
84
    }
85
    PY_CATCH;
86
}
87

88
PyObject* DocumentPy::setPos(PyObject *args)
89
{
90
    char *psFeatStr;
91
    Base::Matrix4D mat;
92
    PyObject *pcMatObj;
93
    if (!PyArg_ParseTuple(args, "sO!;Name of the Feature and the transformation matrix have to be given!",
94
                          &psFeatStr, &(Base::MatrixPy::Type), &pcMatObj))
95
        return nullptr;
96

97
    mat = static_cast<Base::MatrixPy*>(pcMatObj)->value();
98

99
    PY_TRY {
100
        getDocumentPtr()->setPos(psFeatStr,mat);
101
        Py_Return;
102
    }
103
    PY_CATCH;
104
}
105

106
PyObject* DocumentPy::setEdit(PyObject *args)
107
{
108
    char *psFeatStr;
109
    int mod = 0;
110
    char *subname = nullptr;
111
    ViewProvider *vp = nullptr;
112
    App::DocumentObject *obj = nullptr;
113

114
    // by name
115
    if (PyArg_ParseTuple(args, "s|is", &psFeatStr,&mod,&subname)) {
116
        obj = getDocumentPtr()->getDocument()->getObject(psFeatStr);
117
        if (!obj) {
118
            PyErr_Format(Base::PyExc_FC_GeneralError, "No such object found in document: '%s'", psFeatStr);
119
            return nullptr;
120
        }
121
    }
122
    else {
123
        PyErr_Clear();
124
        PyObject *pyObj;
125
        if (!PyArg_ParseTuple(args, "O|is", &pyObj,&mod,&subname))
126
            return nullptr;
127

128
        if (PyObject_TypeCheck(pyObj,&App::DocumentObjectPy::Type)) {
129
            obj = static_cast<App::DocumentObjectPy*>(pyObj)->getDocumentObjectPtr();
130
        }
131
        else if (PyObject_TypeCheck(pyObj,&ViewProviderPy::Type)) {
132
            vp = static_cast<ViewProviderPy*>(pyObj)->getViewProviderPtr();
133
        }
134
        else {
135
            PyErr_SetString(PyExc_TypeError,"Expect the first argument to be string, DocumentObject or ViewObject");
136
            return nullptr;
137
        }
138
    }
139

140
    if (!vp) {
141
        if (!obj || !obj->isAttachedToDocument() || !(vp=Application::Instance->getViewProvider(obj))) {
142
            PyErr_SetString(PyExc_ValueError,"Invalid document object");
143
            return nullptr;
144
        }
145
    }
146

147
    bool ok = getDocumentPtr()->setEdit(vp,mod,subname);
148

149
    return PyBool_FromLong(ok ? 1 : 0);
150
}
151

152
PyObject* DocumentPy::getInEdit(PyObject *args)
153
{
154
    if (!PyArg_ParseTuple(args, ""))
155
        return nullptr;
156

157
    ViewProvider* vp = getDocumentPtr()->getInEdit();
158
    if (vp)
159
        return vp->getPyObject();
160

161
    Py_Return;
162
}
163

164
PyObject* DocumentPy::resetEdit(PyObject *args)
165
{
166
    if (!PyArg_ParseTuple(args, ""))
167
        return nullptr;
168

169
    getDocumentPtr()->resetEdit();
170

171
    Py_Return;
172
}
173

174
PyObject* DocumentPy::addAnnotation(PyObject *args)
175
{
176
    char *psAnnoName,*psFileName,*psModName = nullptr;
177
    if (!PyArg_ParseTuple(args, "ss|s;Name of the Annotation and a file name have to be given!",
178
                          &psAnnoName,&psFileName,&psModName))
179
        return nullptr;
180

181
    PY_TRY {
182
        auto pcExt = new ViewProviderExtern();
183

184
        pcExt->setModeByFile(psModName ? psModName : "Main", psFileName);
185
        pcExt->adjustDocumentName(getDocumentPtr()->getDocument()->getName());
186
        getDocumentPtr()->setAnnotationViewProvider(psAnnoName,pcExt);
187

188
        Py_Return;
189
    }
190
    PY_CATCH;
191
}
192

193
PyObject* DocumentPy::update(PyObject *args)
194
{
195
    if (!PyArg_ParseTuple(args, ""))
196
        return nullptr;
197

198
    PY_TRY {
199
        getDocumentPtr()->onUpdate();
200
        Py_Return;
201
    }
202
    PY_CATCH;
203
}
204

205
PyObject* DocumentPy::getObject(PyObject *args)
206
{
207
    char *sName;
208
    if (!PyArg_ParseTuple(args, "s", &sName))
209
        return nullptr;
210

211
    PY_TRY {
212
        ViewProvider *pcView = getDocumentPtr()->getViewProviderByName(sName);
213
        if (pcView)
214
            return pcView->getPyObject();
215
        else
216
            Py_Return;
217
    }
218
    PY_CATCH;
219
}
220

221
PyObject* DocumentPy::activeObject(PyObject *args)
222
{
223
    if (!PyArg_ParseTuple(args, ""))
224
        return nullptr;
225

226
    PY_TRY {
227
        App::DocumentObject *pcFtr = getDocumentPtr()->getDocument()->getActiveObject();
228
        if (pcFtr) {
229
            ViewProvider *pcView = getDocumentPtr()->getViewProvider(pcFtr);
230
            return pcView->getPyObject();
231
        }
232
        else {
233
            Py_Return;
234
        }
235
    }
236
    PY_CATCH;
237
}
238

239
PyObject* DocumentPy::activeView(PyObject *args)
240
{
241
    if (!PyArg_ParseTuple(args, ""))
242
        return nullptr;
243

244
    PY_TRY {
245
        Gui::MDIView  *pcView = getDocumentPtr()->getActiveView();
246
        if (pcView){
247
            // already incremented in getPyObject().
248
            return pcView->getPyObject();
249
        }
250
        else {
251
            Py_Return;
252
        }
253
    }
254
    PY_CATCH;
255
}
256

257
PyObject* DocumentPy::mdiViewsOfType(PyObject *args)
258
{
259
    char* sType;
260
    if (!PyArg_ParseTuple(args, "s", &sType))
261
        return nullptr;
262

263
    Base::Type type = Base::Type::fromName(sType);
264
    if (type.isBad()) {
265
        PyErr_Format(PyExc_TypeError, "'%s' is not a valid type", sType);
266
        return nullptr;
267
    }
268

269
    PY_TRY {
270
        std::list<Gui::MDIView*> views = getDocumentPtr()->getMDIViewsOfType(type);
271
        Py::List list;
272
        for (auto it : views)
273
            list.append(Py::asObject(it->getPyObject()));
274
        return Py::new_reference_to(list);
275
    }
276
    PY_CATCH;
277
}
278

279
PyObject* DocumentPy::save(PyObject *args)
280
{
281
    if (!PyArg_ParseTuple(args, ""))
282
        return nullptr;
283

284
    PY_TRY {
285
        bool ok = getDocumentPtr()->save();
286
        return Py::new_reference_to(Py::Boolean(ok));
287
    }
288
    PY_CATCH;
289
}
290

291
PyObject* DocumentPy::saveAs(PyObject *args)
292
{
293
    if (!PyArg_ParseTuple(args, ""))
294
        return nullptr;
295

296
    PY_TRY {
297
        bool ok = getDocumentPtr()->saveAs();
298
        return Py::new_reference_to(Py::Boolean(ok));
299
    }
300
    PY_CATCH;
301
}
302

303
PyObject* DocumentPy::sendMsgToViews(PyObject *args)
304
{
305
    char* msg;
306
    if (!PyArg_ParseTuple(args, "s", &msg))
307
        return nullptr;
308

309
    PY_TRY {
310
        getDocumentPtr()->sendMsgToViews(msg);
311
        Py_Return;
312
    }
313
    PY_CATCH;
314
}
315

316
PyObject* DocumentPy::mergeProject(PyObject *args)
317
{
318
    char* filename;
319
    if (!PyArg_ParseTuple(args, "s", &filename))
320
        return nullptr;
321

322
    PY_TRY {
323
        Base::FileInfo fi(filename);
324
        Base::ifstream str(fi, std::ios::in | std::ios::binary);
325
        App::Document* doc = getDocumentPtr()->getDocument();
326
        MergeDocuments md(doc);
327
        md.importObjects(str);
328

329
        Py_Return;
330
    }
331
    PY_CATCH;
332
}
333

334
PyObject* DocumentPy::toggleTreeItem(PyObject *args)
335
{
336
    PyObject *object;
337
    const char *subname = nullptr;
338
    int mod = 0;
339
    if (!PyArg_ParseTuple(args,"O!|is",&(App::DocumentObjectPy::Type), &object,&mod,&subname))
340
        return nullptr;
341

342
    App::DocumentObject* Object = static_cast<App::DocumentObjectPy*>(object)->getDocumentObjectPtr();
343
    App::DocumentObject* parent = nullptr;
344
    if (subname) {
345
        App::DocumentObject* sobj = Object->getSubObject(subname);
346
        if (!sobj) {
347
            PyErr_SetString(PyExc_ValueError, "Subobject not found");
348
            return nullptr;
349
        }
350

351
        parent = Object;
352
        Object = sobj;
353
    }
354

355
    // get the gui document of the Assembly Item
356
    //ActiveAppDoc = Item->getDocument();
357
    //ActiveGuiDoc = Gui::Application::Instance->getDocument(getDocumentPtr());
358
    auto ActiveVp = dynamic_cast<Gui::ViewProviderDocumentObject*>(getDocumentPtr()->getViewProvider(Object));
359
    switch (mod) {
360
        case 0:
361
            getDocumentPtr()->signalExpandObject(*ActiveVp, TreeItemMode::ToggleItem, parent, subname);
362
            break;
363
        case 1:
364
            getDocumentPtr()->signalExpandObject(*ActiveVp, TreeItemMode::CollapseItem, parent, subname);
365
            break;
366
        case 2:
367
            getDocumentPtr()->signalExpandObject(*ActiveVp, TreeItemMode::ExpandItem, parent, subname);
368
            break;
369
        case 3:
370
            getDocumentPtr()->signalExpandObject(*ActiveVp, TreeItemMode::ExpandPath, parent, subname);
371
            break;
372
        default:
373
            PyErr_SetString(PyExc_ValueError, "Item mode out of range");
374
            return nullptr;
375
    }
376

377
    Py_Return;
378
}
379

380
PyObject* DocumentPy::scrollToTreeItem(PyObject *args)
381
{
382
    PyObject *view;
383
    if (!PyArg_ParseTuple(args,"O!",&(Gui::ViewProviderDocumentObjectPy::Type), &view))
384
        return nullptr;
385

386
    Gui::ViewProviderDocumentObject* vp = static_cast<ViewProviderDocumentObjectPy*>
387
            (view)->getViewProviderDocumentObjectPtr();
388
    getDocumentPtr()->signalScrollToObject(*vp);
389

390
    Py_Return;
391
}
392

393
PyObject* DocumentPy::toggleInSceneGraph(PyObject *args) {
394
    PyObject *view;
395
    if (!PyArg_ParseTuple(args,"O!",&(Gui::ViewProviderPy::Type), &view))
396
        return nullptr;
397

398
    Gui::ViewProvider* vp = static_cast<ViewProviderPy*>(view)->getViewProviderPtr();
399
    getDocumentPtr()->toggleInSceneGraph(vp);
400

401
    Py_Return;
402
}
403

404
Py::Object DocumentPy::getActiveObject() const
405
{
406
    App::DocumentObject *object = getDocumentPtr()->getDocument()->getActiveObject();
407
    if (object) {
408
        ViewProvider *viewObj = getDocumentPtr()->getViewProvider(object);
409
        return Py::Object(viewObj->getPyObject(), true);
410
    }
411
    else {
412
        return Py::None();
413
    }
414
}
415

416
void DocumentPy::setActiveObject(Py::Object /*arg*/)
417
{
418
    throw Py::AttributeError("'Document' object attribute 'ActiveObject' is read-only");
419
}
420

421
Py::Object DocumentPy::getActiveView() const
422
{
423
    Gui::MDIView *view = getDocumentPtr()->getActiveView();
424
    if (view) {
425
        // already incremented in getPyObject().
426
        return Py::Object(view->getPyObject(), true);
427
    }
428
    else {
429
        return Py::None();
430
    }
431
}
432

433
void DocumentPy::setActiveView(Py::Object /*arg*/)
434
{
435
    throw Py::AttributeError("'Document' object attribute 'ActiveView' is read-only");
436
}
437

438
Py::Object DocumentPy::getDocument() const
439
{
440
    App::Document *doc = getDocumentPtr()->getDocument();
441
    if (doc) {
442
        // already incremented in getPyObject().
443
        return Py::Object(doc->getPyObject(), true);
444
    }
445
    else {
446
        return Py::None();
447
    }
448
}
449

450
Py::Object DocumentPy::getEditingTransform() const
451
{
452
    return Py::asObject(new Base::MatrixPy(new Base::Matrix4D(
453
                    getDocumentPtr()->getEditingTransform())));
454
}
455

456
void DocumentPy::setEditingTransform(Py::Object arg)
457
{
458
    if (!PyObject_TypeCheck(arg.ptr(),&Base::MatrixPy::Type))
459
        throw Py::TypeError("Expecting type of matrix");
460

461
    getDocumentPtr()->setEditingTransform(
462
            *static_cast<Base::MatrixPy*>(arg.ptr())->getMatrixPtr());
463
}
464

465
Py::Object DocumentPy::getInEditInfo() const {
466
    ViewProviderDocumentObject *vp = nullptr;
467
    std::string subname,subelement;
468
    int mode = 0;
469
    getDocumentPtr()->getInEdit(&vp,&subname,&mode,&subelement);
470
    if (!vp || !vp->getObject() || !vp->getObject()->isAttachedToDocument())
471
        return Py::None();
472

473
    return Py::TupleN(Py::Object(vp->getObject()->getPyObject(),true),
474
            Py::String(subname),Py::String(subelement),Py::Int(mode));
475
}
476

477
void DocumentPy::setInEditInfo(Py::Object arg)
478
{
479
    PyObject *pyobj;
480
    const char *subname;
481
    if (!PyArg_ParseTuple(arg.ptr(), "O!s", &Gui::ViewProviderDocumentObjectPy::Type,
482
                          &pyobj, &subname))
483
        throw Py::Exception();
484

485
    getDocumentPtr()->setInEdit(static_cast<ViewProviderDocumentObjectPy*>(
486
                pyobj)->getViewProviderDocumentObjectPtr(),subname);
487
}
488

489
Py::Int DocumentPy::getEditMode() const
490
{
491
    int mode = -1;
492
    getDocumentPtr()->getInEdit(nullptr,nullptr,&mode);
493

494
    return Py::Int(mode);
495
}
496

497
Py::Boolean DocumentPy::getTransacting() const
498
{
499
    return {getDocumentPtr()->isPerformingTransaction()};
500
}
501

502
Py::Boolean DocumentPy::getModified() const
503
{
504
    return {getDocumentPtr()->isModified()};
505
}
506

507
void DocumentPy::setModified(Py::Boolean arg)
508
{
509
    getDocumentPtr()->setModified(arg);
510
}
511

512
Py::List DocumentPy::getTreeRootObjects() const
513
{
514
    std::vector<App::DocumentObject*> objs = getDocumentPtr()->getTreeRootObjects();
515
    Py::List res;
516

517
    for (auto obj : objs) {
518
        //Note: Here we must force the Py::Object to own this Python object as getPyObject() increments the counter
519
        res.append(Py::Object(obj->getPyObject(), true));
520
    }
521

522
    return res;
523
}
524

525

526
PyObject *DocumentPy::getCustomAttributes(const char* attr) const
527
{
528
    // Note: Here we want to return only a document object if its
529
    // name matches 'attr'. However, it is possible to have an object
530
    // with the same name as an attribute. If so, we return 0 as other-
531
    // wise it wouldn't be possible to address this attribute any more.
532
    // The object must then be addressed by the getObject() method directly.
533
    if (!this->ob_type->tp_dict) {
534
        if (PyType_Ready(this->ob_type) < 0)
535
            return nullptr;
536
    }
537

538
    PyObject* item = PyDict_GetItemString(this->ob_type->tp_dict, attr);
539
    if (item)
540
        return nullptr;
541

542
    // search for an object with this name
543
    ViewProvider* obj = getDocumentPtr()->getViewProviderByName(attr);
544

545
    return (obj ? obj->getPyObject() : nullptr);
546
}
547

548
int DocumentPy::setCustomAttributes(const char* attr, PyObject *)
549
{
550
    // Note: Here we want to return only a document object if its
551
    // name matches 'attr'. However, it is possible to have an object
552
    // with the same name as an attribute. If so, we return 0 as other-
553
    // wise it wouldn't be possible to address this attribute any more.
554
    // The object must then be addressed by the getObject() method directly.
555
    if (!this->ob_type->tp_dict) {
556
        if (PyType_Ready(this->ob_type) < 0)
557
            return 0;
558
    }
559

560
    PyObject* item = PyDict_GetItemString(this->ob_type->tp_dict, attr);
561
    if (item)
562
        return 0;
563

564
    ViewProvider* obj = getDocumentPtr()->getViewProviderByName(attr);
565
    if (obj) {
566
        std::stringstream str;
567
        str << "'Document' object attribute '" << attr
568
            << "' must not be set this way" << std::ends;
569
        throw Py::AttributeError(str.str());
570
    }
571

572
    return 0;
573
}
574

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

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

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

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