FreeCAD

Форк
0
/
DocumentObserverPython.cpp 
260 строк · 9.5 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2018 Stefan Tröger <stefantroeger@gmx.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
#include <Base/Interpreter.h>
26

27
#include "Application.h"
28
#include "Document.h"
29
#include "DocumentObserverPython.h"
30
#include "ViewProvider.h"
31
#include "ViewProviderDocumentObject.h"
32

33

34
using namespace Gui;
35
namespace sp = std::placeholders;
36

37
std::vector<DocumentObserverPython*> DocumentObserverPython::_instances;
38

39
void DocumentObserverPython::addObserver(const Py::Object& obj)
40
{
41
    _instances.push_back(new DocumentObserverPython(obj));
42
}
43

44
void DocumentObserverPython::removeObserver(const Py::Object& obj)
45
{
46
    DocumentObserverPython* obs=nullptr;
47
    for (std::vector<DocumentObserverPython*>::iterator it =
48
        _instances.begin(); it != _instances.end(); ++it) {
49
        if ((*it)->inst == obj) {
50
            obs = *it;
51
            _instances.erase(it);
52
            break;
53
        }
54
    }
55

56
    delete obs;
57
}
58

59
DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj)
60
{
61
    //NOLINTBEGIN
62
#define FC_PY_ELEMENT_ARG1(_name1, _name2) do {\
63
        FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py);\
64
        if (!py##_name1.py.isNone())\
65
            py##_name1.slot = Application::Instance->signal##_name2.connect(\
66
                    std::bind(&DocumentObserverPython::slot##_name1, this, sp::_1));\
67
    }\
68
    while(0);
69

70
#define FC_PY_ELEMENT_ARG2(_name1, _name2) do {\
71
        FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py);\
72
        if (!py##_name1.py.isNone())\
73
            py##_name1.slot = Application::Instance->signal##_name2.connect(\
74
                    std::bind(&DocumentObserverPython::slot##_name1, this, sp::_1, sp::_2));\
75
    }\
76
    while(0);
77

78
    FC_PY_ELEMENT_ARG1(CreatedDocument, NewDocument)
79
    FC_PY_ELEMENT_ARG1(DeletedDocument, DeleteDocument)
80
    FC_PY_ELEMENT_ARG1(RelabelDocument, RelabelDocument)
81
    FC_PY_ELEMENT_ARG1(RenameDocument, RenameDocument)
82
    FC_PY_ELEMENT_ARG1(ActivateDocument, ActiveDocument)
83
    FC_PY_ELEMENT_ARG1(CreatedObject, NewObject)
84
    FC_PY_ELEMENT_ARG1(DeletedObject, DeletedObject)
85
    FC_PY_ELEMENT_ARG2(BeforeChangeObject, BeforeChangeObject)
86
    FC_PY_ELEMENT_ARG2(ChangedObject, ChangedObject)
87
    FC_PY_ELEMENT_ARG1(InEdit, InEdit)
88
    FC_PY_ELEMENT_ARG1(ResetEdit, ResetEdit)
89
    //NOLINTEND
90
}
91

92
DocumentObserverPython::~DocumentObserverPython() = default;
93

94
void DocumentObserverPython::slotCreatedDocument(const Gui::Document& Doc)
95
{
96
    Base::PyGILStateLocker lock;
97
    try {
98
        Py::Tuple args(1);
99
        args.setItem(0, Py::asObject(const_cast<Gui::Document&>(Doc).getPyObject()));
100
        Base::pyCall(pyCreatedDocument.ptr(),args.ptr());
101
    }
102
    catch (Py::Exception&) {
103
        Base::PyException e; // extract the Python error text
104
        e.ReportException();
105
    }
106
}
107

108
void DocumentObserverPython::slotDeletedDocument(const Gui::Document& Doc)
109
{
110
    Base::PyGILStateLocker lock;
111
    try {
112
        Py::Tuple args(1);
113
        args.setItem(0, Py::asObject(const_cast<Gui::Document&>(Doc).getPyObject()));
114
        Base::pyCall(pyDeletedDocument.ptr(),args.ptr());
115
    }
116
    catch (Py::Exception&) {
117
        Base::PyException e; // extract the Python error text
118
        e.ReportException();
119
    }
120
}
121

122
void DocumentObserverPython::slotRelabelDocument(const Gui::Document& Doc)
123
{
124
    Base::PyGILStateLocker lock;
125
    try {
126
        Py::Tuple args(1);
127
        args.setItem(0, Py::asObject(const_cast<Gui::Document&>(Doc).getPyObject()));
128
        Base::pyCall(pyRelabelDocument.ptr(),args.ptr());
129
    }
130
    catch (Py::Exception&) {
131
        Base::PyException e; // extract the Python error text
132
        e.ReportException();
133
    }
134
}
135

136
void DocumentObserverPython::slotRenameDocument(const Gui::Document& Doc)
137
{
138
    Base::PyGILStateLocker lock;
139
    try {
140
        Py::Tuple args(1);
141
        args.setItem(0, Py::asObject(const_cast<Gui::Document&>(Doc).getPyObject()));
142
        Base::pyCall(pyRenameDocument.ptr(),args.ptr());
143
    }
144
    catch (Py::Exception&) {
145
        Base::PyException e; // extract the Python error text
146
        e.ReportException();
147
    }
148
}
149

150
void DocumentObserverPython::slotActivateDocument(const Gui::Document& Doc)
151
{
152
    Base::PyGILStateLocker lock;
153
    try {
154
        Py::Tuple args(1);
155
        args.setItem(0, Py::asObject(const_cast<Gui::Document&>(Doc).getPyObject()));
156
        Base::pyCall(pyActivateDocument.ptr(),args.ptr());
157
    }
158
    catch (Py::Exception&) {
159
        Base::PyException e; // extract the Python error text
160
        e.ReportException();
161
    }
162
}
163

164
void DocumentObserverPython::slotCreatedObject(const Gui::ViewProvider& Obj)
165
{
166
    Base::PyGILStateLocker lock;
167
    try {
168
        Py::Tuple args(1);
169
        args.setItem(0, Py::asObject(const_cast<Gui::ViewProvider&>(Obj).getPyObject()));
170
        Base::pyCall(pyCreatedObject.ptr(),args.ptr());
171
    }
172
    catch (Py::Exception&) {
173
        Base::PyException e; // extract the Python error text
174
        e.ReportException();
175
    }
176
}
177

178
void DocumentObserverPython::slotDeletedObject(const Gui::ViewProvider& Obj)
179
{
180
    Base::PyGILStateLocker lock;
181
    try {
182
        Py::Tuple args(1);
183
        args.setItem(0, Py::asObject(const_cast<Gui::ViewProvider&>(Obj).getPyObject()));
184
        Base::pyCall(pyDeletedObject.ptr(),args.ptr());
185
    }
186
    catch (Py::Exception&) {
187
        Base::PyException e; // extract the Python error text
188
        e.ReportException();
189
    }
190
}
191

192
void DocumentObserverPython::slotBeforeChangeObject(const Gui::ViewProvider& Obj,
193
                                                    const App::Property& Prop)
194
{
195
    Base::PyGILStateLocker lock;
196
    try {
197
        Py::Tuple args(2);
198
        args.setItem(0, Py::asObject(const_cast<Gui::ViewProvider&>(Obj).getPyObject()));
199
        // If a property is touched but not part of a document object then its name is null.
200
        // In this case the slot function must not be called.
201
        const char* prop_name = Obj.getPropertyName(&Prop);
202
        if (prop_name) {
203
            args.setItem(1, Py::String(prop_name));
204
            Base::pyCall(pyBeforeChangeObject.ptr(),args.ptr());
205
        }
206
    }
207
    catch (Py::Exception&) {
208
        Base::PyException e; // extract the Python error text
209
        e.ReportException();
210
    }
211
}
212

213
void DocumentObserverPython::slotChangedObject(const Gui::ViewProvider& Obj,
214
                                               const App::Property& Prop)
215
{
216
    Base::PyGILStateLocker lock;
217
    try {
218
        Py::Tuple args(2);
219
        args.setItem(0, Py::asObject(const_cast<Gui::ViewProvider&>(Obj).getPyObject()));
220
        // If a property is touched but not part of a document object then its name is null.
221
        // In this case the slot function must not be called.
222
        const char* prop_name = Obj.getPropertyName(&Prop);
223
        if (prop_name) {
224
            args.setItem(1, Py::String(prop_name));
225
            Base::pyCall(pyChangedObject.ptr(),args.ptr());
226
        }
227
    }
228
    catch (Py::Exception&) {
229
        Base::PyException e; // extract the Python error text
230
        e.ReportException();
231
    }
232
}
233

234
void DocumentObserverPython::slotInEdit(const Gui::ViewProviderDocumentObject& Obj)
235
{
236
    Base::PyGILStateLocker lock;
237
    try {
238
        Py::Tuple args(1);
239
        args.setItem(0, Py::asObject(const_cast<Gui::ViewProviderDocumentObject&>(Obj).getPyObject()));
240
        Base::pyCall(pyInEdit.ptr(),args.ptr());
241
    }
242
    catch (Py::Exception&) {
243
        Base::PyException e; // extract the Python error text
244
        e.ReportException();
245
    }
246
}
247

248
void DocumentObserverPython::slotResetEdit(const Gui::ViewProviderDocumentObject& Obj)
249
{
250
    Base::PyGILStateLocker lock;
251
    try {
252
        Py::Tuple args(1);
253
        args.setItem(0, Py::asObject(const_cast<Gui::ViewProviderDocumentObject&>(Obj).getPyObject()));
254
        Base::pyCall(pyResetEdit.ptr(),args.ptr());
255
    }
256
    catch (Py::Exception&) {
257
        Base::PyException e; // extract the Python error text
258
        e.ReportException();
259
    }
260
}
261

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

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

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

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