Xcos MVC: implement clone / delete on the Model side
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / DiagramAdapter.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  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 #include <string>
14 #include <vector>
15 #include <sstream>
16
17 #include "internal.hxx"
18 #include "double.hxx"
19 #include "list.hxx"
20 #include "tlist.hxx"
21 #include "string.hxx"
22 #include "types.hxx"
23 #include "user.hxx"
24
25 #include "utilities.hxx"
26 #include "Controller.hxx"
27 #include "DiagramAdapter.hxx"
28 #include "Adapters.hxx"
29 #include "ParamsAdapter.hxx"
30 #include "TextAdapter.hxx"
31 #include "BlockAdapter.hxx"
32 #include "LinkAdapter.hxx"
33 #include "model/BaseObject.hxx"
34
35 extern "C" {
36 #include "sci_malloc.h"
37 #include "charEncoding.h"
38 }
39
40 namespace org_scilab_modules_scicos
41 {
42 namespace view_scilab
43 {
44 namespace
45 {
46
47 struct props
48 {
49
50     static types::InternalType* get(const DiagramAdapter& adaptor, const Controller& controller)
51     {
52         ParamsAdapter localAdaptor = ParamsAdapter(false, adaptor.getAdaptee());
53         return localAdaptor.getAsTList(new types::TList(), controller);
54     }
55
56     static bool set(DiagramAdapter& adaptor, types::InternalType* v, Controller& controller)
57     {
58         ParamsAdapter localAdaptor = ParamsAdapter(false, adaptor.getAdaptee());
59         return localAdaptor.setAsTList(v, controller);
60     }
61 };
62
63 struct objs
64 {
65
66     static types::InternalType* get(const DiagramAdapter& adaptor, const Controller& controller)
67     {
68         // FIXME: get all children of the Diagram and return them as a list
69         model::Diagram* adaptee = adaptor.getAdaptee();
70
71         std::vector<ScicosID> children;
72         controller.getObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, children);
73
74         types::List* o = new types::List();
75
76         for (int i = 0; i < static_cast<int>(children.size()); ++i)
77         {
78             model::BaseObject* item = Controller().getObject(children[i]);
79             switch (item->kind())
80             {
81                 case ANNOTATION:
82                 {
83                     model::Annotation* annotation = static_cast<model::Annotation*>(item);
84                     TextAdapter* localAdaptor = new TextAdapter(false, annotation);
85                     o->set(i, localAdaptor);
86                     continue;
87                 }
88                 case BLOCK:
89                 {
90                     model::Block* block = static_cast<model::Block*>(item);
91                     BlockAdapter* localAdaptor = new BlockAdapter(false, block);
92                     o->set(i, localAdaptor);
93                     continue;
94                 }
95                 case LINK:
96                 {
97                     model::Link* link = static_cast<model::Link*>(item);
98                     LinkAdapter* localAdaptor = new LinkAdapter(false, link);
99                     o->set(i, localAdaptor);
100                     continue;
101                 }
102                 default:
103                     return 0;
104             }
105         }
106         return o;
107     }
108
109     static bool set(DiagramAdapter& adaptor, types::InternalType* v, Controller& controller)
110     {
111         // FIXME implement, decode the list and set all children of the Diagram
112         if (v->getType() != types::InternalType::ScilabList)
113         {
114             return false;
115         }
116
117         model::Diagram* adaptee = adaptor.getAdaptee();
118
119         types::List* list = v->getAs<types::List>();
120         std::vector<ScicosID> diagramChildren (list->getSize());
121         for (int i = 0; i < list->getSize(); ++i)
122         {
123             if (list->get(i)->getType() != types::InternalType::ScilabUserType)
124             {
125                 return false;
126             }
127
128             // Find the type of the input object through Adapters' mapping.
129             const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(list->get(i)->getShortTypeStr());
130
131             // Then, each adapter gets linked to the diagram through its adaptee (PARENT_DIAGRAM)
132             // and the diagram's adaptee lists its adaptees (CHILDREN).
133             ScicosID id;
134             switch (adapter_index)
135             {
136                 case Adapters::BLOCK_ADAPTER:
137                 {
138                     BlockAdapter* modelElement = list->get(i)->getAs<BlockAdapter>();
139                     model::Block* subAdaptee = modelElement->getAdaptee();
140
141                     controller.setObjectProperty(id, subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
142                     id = subAdaptee->id();
143                     break;
144                 }
145                 case Adapters::LINK_ADAPTER:
146                 {
147                     LinkAdapter* modelElement = list->get(i)->getAs<LinkAdapter>();
148                     model::Link* subAdaptee = modelElement->getAdaptee();
149
150                     controller.setObjectProperty(subAdaptee->id(), subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
151                     id = subAdaptee->id();
152                     break;
153                 }
154                 case Adapters::TEXT_ADAPTER:
155                 {
156                     TextAdapter* modelElement = list->get(i)->getAs<TextAdapter>();
157                     model::Annotation* subAdaptee = modelElement->getAdaptee();
158
159                     controller.setObjectProperty(subAdaptee->id(), subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
160                     id = subAdaptee->id();
161                     break;
162                 }
163                 default:
164                     return false;
165             }
166
167             diagramChildren[i] = id;
168         }
169
170         controller.setObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
171         return true;
172     }
173 };
174
175 struct version
176 {
177
178     static types::InternalType* get(const DiagramAdapter& adaptor, const Controller& controller)
179     {
180         model::Diagram* adaptee = adaptor.getAdaptee();
181
182         std::string version;
183         controller.getObjectProperty(adaptee->id(), adaptee->kind(), VERSION_NUMBER, version);
184
185         return new types::String(version.data());
186     }
187
188     static bool set(DiagramAdapter& adaptor, types::InternalType* v, Controller& controller)
189     {
190         if (v->getType() == types::InternalType::ScilabString)
191         {
192             types::String* current = v->getAs<types::String>();
193             if (current->getSize() != 1)
194             {
195                 return false;
196             }
197
198             model::Diagram* adaptee = adaptor.getAdaptee();
199
200             char* c_str = wide_string_to_UTF8(current->get(0));
201             std::string version (c_str);
202             FREE(c_str);
203
204             controller.setObjectProperty(adaptee->id(), adaptee->kind(), VERSION_NUMBER, version);
205             return true;
206         }
207         else if (v->getType() == types::InternalType::ScilabDouble)
208         {
209             types::Double* current = v->getAs<types::Double>();
210             if (current->getSize() != 0)
211             {
212                 return false;
213             }
214
215             model::Diagram* adaptee = adaptor.getAdaptee();
216
217             std::string version;
218             controller.setObjectProperty(adaptee->id(), adaptee->kind(), VERSION_NUMBER, version);
219             return true;
220         }
221
222         return false;
223     }
224 };
225
226 struct contrib
227 {
228
229     static types::InternalType* get(const DiagramAdapter& adaptor, const Controller& controller)
230     {
231         // silent unused parameter warnings
232         (void) controller;
233
234         return adaptor.getContribContent();
235     }
236
237     static bool set(DiagramAdapter& adaptor, types::InternalType* v, Controller& controller)
238     {
239         // silent unused parameter warnings
240         (void) v;
241         (void) controller;
242
243         adaptor.setContribContent(v->clone());
244         return true;
245     }
246 };
247
248 } /* namespace */
249
250 template<> property<DiagramAdapter>::props_t property<DiagramAdapter>::fields = property<DiagramAdapter>::props_t();
251
252 DiagramAdapter::DiagramAdapter(bool ownAdaptee, org_scilab_modules_scicos::model::Diagram* adaptee) :
253     BaseAdapter<DiagramAdapter, org_scilab_modules_scicos::model::Diagram>(ownAdaptee, adaptee)
254 {
255     if (property<DiagramAdapter>::properties_have_not_been_set())
256     {
257         property<DiagramAdapter>::fields.reserve(4);
258         property<DiagramAdapter>::add_property(L"props", &props::get, &props::set);
259         property<DiagramAdapter>::add_property(L"objs", &objs::get, &objs::set);
260         property<DiagramAdapter>::add_property(L"version", &version::get, &version::set);
261         property<DiagramAdapter>::add_property(L"contrib", &contrib::get, &contrib::set);
262     }
263
264     contrib_content = new types::List();
265 }
266
267 DiagramAdapter::~DiagramAdapter()
268 {
269     delete contrib_content;
270 }
271
272 std::wstring DiagramAdapter::getTypeStr()
273 {
274     return getSharedTypeStr();
275 }
276 std::wstring DiagramAdapter::getShortTypeStr()
277 {
278     return getSharedTypeStr();
279 }
280
281 types::InternalType* DiagramAdapter::getContribContent() const
282 {
283     return contrib_content->clone();
284 }
285
286 void DiagramAdapter::setContribContent(types::InternalType* v)
287 {
288     delete contrib_content;
289     contrib_content = v->clone();
290 }
291
292 } /* namespace view_scilab */
293 } /* namespace org_scilab_modules_scicos */