eecafeee45623c17bc6b68f023061e13efddee52
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / BlockAdapter.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 #include <cwchar>
17
18 #include <string>
19 #include <vector>
20
21 #include "internal.hxx"
22 #include "list.hxx"
23 #include "mlist.hxx"
24 #include "string.hxx"
25 #include "types.hxx"
26
27 #include "utilities.hxx"
28 #include "adapters_utilities.hxx"
29 #include "Controller.hxx"
30 #include "model/Block.hxx"
31 #include "BlockAdapter.hxx"
32 #include "DiagramAdapter.hxx"
33 #include "GraphicsAdapter.hxx"
34 #include "LinkAdapter.hxx"
35 #include "ModelAdapter.hxx"
36 #include "TextAdapter.hxx"
37
38 extern "C" {
39 #include "sci_malloc.h"
40 #include "charEncoding.h"
41 }
42
43 namespace org_scilab_modules_scicos
44 {
45 namespace view_scilab
46 {
47 namespace
48 {
49
50 struct graphics
51 {
52     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
53     {
54         GraphicsAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()));
55         types::InternalType* v = localAdaptor.getAsTList(new types::MList(), controller);
56         return v;
57     }
58
59     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
60     {
61         GraphicsAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()));
62         return localAdaptor.setAsTList(v, controller);
63     }
64 };
65
66 struct model
67 {
68     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
69     {
70         // If we are in a Superblock (has children) then reconstruct a DiagramAdapter, referencing the children
71         DiagramAdapter* subDiagram = nullptr;
72         std::vector<ScicosID> children;
73         controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, children);
74         if (!children.empty())
75         {
76             if (adaptor.getListObjects()->getSize() > 0)
77             {
78                 Controller neededController = const_cast<Controller&>(controller);
79                 ScicosID newDiag = neededController.createObject(DIAGRAM);
80                 subDiagram = new DiagramAdapter(controller, static_cast<org_scilab_modules_scicos::model::Diagram*>(controller.getObject(newDiag)));
81                 neededController.setObjectProperty(newDiag, DIAGRAM, CHILDREN, children);
82
83                 for (const ScicosID id : children)
84                 {
85                     auto o = controller.getObject(id);
86                     neededController.setObjectProperty(o->id(), o->kind(), PARENT_DIAGRAM, newDiag);
87                     neededController.referenceObject(o->id());
88                 }
89                 subDiagram->setFrom(adaptor.getFrom());
90                 subDiagram->setTo(adaptor.getTo());
91                 subDiagram->setListObjects(adaptor.getListObjects());
92                 subDiagram->setContribContent(adaptor.getContribContent());
93
94                 std::vector<std::string> context;
95                 controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, DIAGRAM_CONTEXT, context);
96                 neededController.setObjectProperty(newDiag, DIAGRAM, DIAGRAM_CONTEXT, context);
97             }
98             else
99             {
100                 // The children adapters list has not been set yet. Create it, update the adapter and return.
101                 types::List* listObjects = new types::List();
102                 std::vector<link_t> from;
103                 std::vector<link_t> to;
104                 for (const ScicosID id : children)
105                 {
106                     auto o = controller.getObject(id);
107                     controller.referenceObject(o);
108
109                     switch (o->kind())
110                     {
111                         case ANNOTATION :
112                             listObjects->append(new TextAdapter(controller, static_cast<org_scilab_modules_scicos::model::Annotation*>(o)));
113                             break;
114                         case BLOCK :
115                         {
116                             BlockAdapter* block = new BlockAdapter(controller, static_cast<org_scilab_modules_scicos::model::Block*>(o));
117                             listObjects->append(block);
118                             break;
119                         }
120                         default : // LINK
121                             LinkAdapter* link = new LinkAdapter(controller, static_cast<org_scilab_modules_scicos::model::Link*>(o));
122                             from.push_back(link->getFrom());
123                             to.push_back(link->getTo());
124                             listObjects->append(link);
125                             break;
126                     }
127                 }
128                 const_cast<BlockAdapter&>(adaptor).setFrom(from);
129                 const_cast<BlockAdapter&>(adaptor).setTo(to);
130                 const_cast<BlockAdapter&>(adaptor).setListObjects(listObjects);
131                 return nullptr;
132             }
133         }
134
135         ModelAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()), subDiagram);
136         types::InternalType* mlist = localAdaptor.getAsTList(new types::MList(), controller)->getAs<types::MList>();
137
138         if (localAdaptor.getDiagram() != nullptr)
139         {
140             // To handle the copy constructor case calling model::set
141             const_cast<BlockAdapter&>(adaptor).setFrom(localAdaptor.getDiagram()->getFrom());
142             const_cast<BlockAdapter&>(adaptor).setTo(localAdaptor.getDiagram()->getTo());
143             const_cast<BlockAdapter&>(adaptor).setListObjects(localAdaptor.getDiagram()->getListObjects());
144             const_cast<BlockAdapter&>(adaptor).setContribContent(localAdaptor.getDiagram()->getContribContent());
145         }
146
147         return mlist;
148     }
149
150     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
151     {
152         ModelAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()), nullptr);
153         if (!localAdaptor.setAsTList(v, controller))
154         {
155             return false;
156         }
157
158         if (localAdaptor.getDiagram() != nullptr)
159         {
160             adaptor.setFrom(localAdaptor.getDiagram()->getFrom());
161             adaptor.setTo(localAdaptor.getDiagram()->getTo());
162             adaptor.setListObjects(localAdaptor.getDiagram()->getListObjects());
163             adaptor.setContribContent(localAdaptor.getDiagram()->getContribContent());
164         }
165         return true;
166     }
167 };
168
169 struct gui
170 {
171     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
172     {
173         std::string Interface;
174         ScicosID adaptee = adaptor.getAdaptee()->id();
175         controller.getObjectProperty(adaptee, BLOCK, INTERFACE_FUNCTION, Interface);
176
177         return new types::String(Interface.data());
178     }
179
180     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
181     {
182         if (v->getType() != types::InternalType::ScilabString)
183         {
184             return false;
185         }
186
187         types::String* current = v->getAs<types::String>();
188         if (!current->isScalar())
189         {
190             return false;
191         }
192
193         wchar_t* w_name = current->get(0);
194         char* name = wide_string_to_UTF8(w_name);
195         std::string stName(name);
196         FREE(name);
197
198         ScicosID adaptee = adaptor.getAdaptee()->id();
199         controller.setObjectProperty(adaptee, BLOCK, INTERFACE_FUNCTION, stName);
200         return true;
201     }
202 };
203
204 struct doc
205 {
206     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& /*controller*/)
207     {
208         return adaptor.getDocContent();
209     }
210
211     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& /*controller*/)
212     {
213         adaptor.setDocContent(v->clone());
214         return true;
215     }
216 };
217
218 } /* namespace */
219
220 template<> property<BlockAdapter>::props_t property<BlockAdapter>::fields = property<BlockAdapter>::props_t();
221
222 BlockAdapter::BlockAdapter(const Controller& c, org_scilab_modules_scicos::model::Block* adaptee) :
223     BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
224     doc_content(nullptr),
225     from_vec(),
226     to_vec(),
227     list_objects(nullptr),
228     contrib_content(nullptr)
229 {
230     if (property<BlockAdapter>::properties_have_not_been_set())
231     {
232         property<BlockAdapter>::fields.reserve(4);
233         property<BlockAdapter>::add_property(L"graphics", &graphics::get, &graphics::set);
234         property<BlockAdapter>::add_property(L"model", &model::get, &model::set);
235         property<BlockAdapter>::add_property(L"gui", &gui::get, &gui::set);
236         property<BlockAdapter>::add_property(L"doc", &doc::get, &doc::set);
237     }
238
239     setListObjects(new types::List());
240     setContribContent(new types::List());
241     setDocContent(new types::List());
242
243     // model::get will set the adapter's content (listObjects, from_vec & to_vec) if needed
244     Controller controller;
245     model::get(*this, controller);
246
247 }
248
249 BlockAdapter::BlockAdapter(const BlockAdapter& adapter) :
250     BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(adapter, false),
251     doc_content(nullptr),
252     from_vec(),
253     to_vec(),
254     list_objects(nullptr),
255     contrib_content(nullptr)
256 {
257     Controller controller;
258
259     if (adapter.getListObjects()->getSize() > 0)
260     {
261         types::InternalType* model = model::get(adapter, controller);
262         model::set(*this, model, controller);
263         model->killMe();
264     }
265     else
266     {
267         setListObjects(new types::List());
268         setContribContent(new types::List());
269     }
270
271     setDocContent(adapter.getDocContent());
272 }
273
274 BlockAdapter::~BlockAdapter()
275 {
276     // CHILDREN will be unreferenced on Controller::deleteObject
277
278     if (list_objects != nullptr)
279     {
280         list_objects->DecreaseRef();
281         list_objects->killMe();
282     }
283
284     if (contrib_content != nullptr)
285     {
286         contrib_content->DecreaseRef();
287         contrib_content->killMe();
288     }
289
290     doc_content->DecreaseRef();
291     doc_content->killMe();
292 }
293
294 std::wstring BlockAdapter::getTypeStr()
295 {
296     return getSharedTypeStr();
297 }
298
299 std::wstring BlockAdapter::getShortTypeStr()
300 {
301     return getSharedTypeStr();
302 }
303
304 types::InternalType* BlockAdapter::getDocContent() const
305 {
306     return doc_content;
307 }
308
309 void BlockAdapter::setDocContent(types::InternalType* v)
310 {
311     types::InternalType* temp = doc_content;
312
313     v->IncreaseRef();
314     doc_content = v;
315
316     if (temp != nullptr)
317     {
318         temp->DecreaseRef();
319         temp->killMe();
320     }
321 }
322
323 std::vector<link_t> BlockAdapter::getFrom() const
324 {
325     return from_vec;
326 }
327
328 void BlockAdapter::setFrom(const std::vector<link_t>& from)
329 {
330     from_vec = from;
331 }
332
333 std::vector<link_t> BlockAdapter::getTo() const
334 {
335     return to_vec;
336 }
337
338 void BlockAdapter::setTo(const std::vector<link_t>& to)
339 {
340     to_vec = to;
341 }
342
343 types::List* BlockAdapter::getListObjects() const
344 {
345     return list_objects;
346 }
347
348 void BlockAdapter::setListObjects(types::List* v)
349 {
350     types::InternalType* temp = list_objects;
351
352     // Do not check if v is nullptr on purpose ; it *should* not
353     v->IncreaseRef();
354     list_objects = v;
355
356     if (temp != nullptr)
357     {
358         temp->DecreaseRef();
359         temp->killMe();
360     }
361 }
362
363 types::InternalType* BlockAdapter::getContribContent() const
364 {
365     return contrib_content;
366 }
367
368 void BlockAdapter::setContribContent(types::InternalType* v)
369 {
370     types::InternalType* temp = contrib_content;
371
372     // do not check if v is nullptr on purpose ; it *should* not
373     v->IncreaseRef();
374     contrib_content = v;
375
376     if (temp != nullptr)
377     {
378         temp->DecreaseRef();
379         temp->killMe();
380     }
381 }
382
383 } /* namespace view_scilab */
384 } /* namespace org_scilab_modules_scicos */