Xcos MVC: allow column vectors for all properties
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / ParamsAdapter.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 <algorithm>
16
17 #include "double.hxx"
18 #include "string.hxx"
19 #include "bool.hxx"
20 #include "list.hxx"
21 #include "tlist.hxx"
22
23 #include "utilities.hxx"
24 #include "Controller.hxx"
25 #include "ParamsAdapter.hxx"
26
27 extern "C" {
28 #include "sci_malloc.h"
29 #include "charEncoding.h"
30 }
31
32 namespace org_scilab_modules_scicos
33 {
34 namespace view_scilab
35 {
36 namespace
37 {
38
39 const std::wstring scsopt(L"scsopt");
40 const std::wstring ThreeD(L"3D");
41 const std::wstring Background(L"Background");
42 const std::wstring Link(L"Link");
43 const std::wstring ID(L"ID");
44 const std::wstring Cmap(L"Cmap");
45
46 struct dummy_property
47 {
48
49     static types::InternalType* get(const ParamsAdapter& /*adaptor*/, const Controller& /*controller*/)
50     {
51         // Return a default empty matrix.
52         return types::Double::Empty();
53     }
54
55     static bool set(ParamsAdapter& /*adaptor*/, types::InternalType* /*v*/, Controller& /*controller*/)
56     {
57         // everything should be right as the properties mapped using this adapter do not perform anything
58         return true;
59     }
60 };
61
62 struct title
63 {
64
65     static types::InternalType* get(const ParamsAdapter& adaptor, const Controller& controller)
66     {
67         ScicosID adaptee = adaptor.getAdaptee()->id();
68
69         std::string title;
70         controller.getObjectProperty(adaptee, DIAGRAM, TITLE, title);
71         std::string path;
72         controller.getObjectProperty(adaptee, DIAGRAM, PATH, path);
73
74         types::String* o = new types::String(2, 1);
75         o->set(0, title.data());
76         o->set(1, path.data());
77
78         return o;
79     }
80
81     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& controller)
82     {
83         if (v->getType() != types::InternalType::ScilabString)
84         {
85             return false;
86         }
87
88         ScicosID adaptee = adaptor.getAdaptee()->id();
89
90         std::string path;
91         std::string title;
92         types::String* current = v->getAs<types::String>();
93         if (current->getSize() == 1)
94         {
95             // Pass an empty path
96         }
97         else if (current->getSize() == 2)
98         {
99             char* Path = wide_string_to_UTF8(current->get(1));
100             path = std::string(Path);
101             FREE(Path);
102         }
103         else
104         {
105             return false;
106         }
107
108         char* Title = wide_string_to_UTF8(current->get(0));
109         title = std::string(Title);
110         FREE(Title);
111
112         controller.setObjectProperty(adaptee, DIAGRAM, TITLE, title);
113         controller.setObjectProperty(adaptee, DIAGRAM, PATH, path);
114         return true;
115     }
116 };
117
118 struct tol
119 {
120
121     static types::InternalType* get(const ParamsAdapter& adaptor, const Controller& controller)
122     {
123         ScicosID adaptee = adaptor.getAdaptee()->id();
124
125         double* data;
126         types::Double* o = new types::Double(1, 7, &data);
127
128         std::vector<double> tol;
129         controller.getObjectProperty(adaptee, DIAGRAM, PROPERTIES, tol);
130 #ifdef _MSC_VER
131         std::copy(tol.begin() + 1, tol.end(), stdext::checked_array_iterator<double*>( data, 7 ));
132 #else
133         std::copy(tol.begin() + 1, tol.end(), data);
134 #endif
135
136         return o;
137     }
138
139     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& controller)
140     {
141
142         if (v->getType() != types::InternalType::ScilabDouble)
143         {
144             return false;
145         }
146
147         types::Double* current = v->getAs<types::Double>();
148         if (current->getSize() != 6 && current->getSize() != 7)
149         {
150             return false;
151         }
152
153         ScicosID adaptee = adaptor.getAdaptee()->id();
154
155         std::vector<double> tol;
156         controller.getObjectProperty(adaptee, DIAGRAM, PROPERTIES, tol);
157
158         std::copy(current->getReal(), current->getReal() + current->getSize(), tol.begin() + 1);
159
160         // In case the last parameter is missing
161         if (current->getSize() == 6)
162         {
163             tol[7] = 0;
164         }
165
166         controller.setObjectProperty(adaptee, DIAGRAM, PROPERTIES, tol);
167         return true;
168     }
169 };
170
171 struct tf
172 {
173
174     static types::InternalType* get(const ParamsAdapter& adaptor, const Controller& controller)
175     {
176         ScicosID adaptee = adaptor.getAdaptee()->id();
177
178         std::vector<double> tf;
179         controller.getObjectProperty(adaptee, DIAGRAM, PROPERTIES, tf);
180
181         return new types::Double(tf[0]);
182     }
183
184     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& controller)
185     {
186
187         if (v->getType() != types::InternalType::ScilabDouble)
188         {
189             return false;
190         }
191
192         types::Double* current = v->getAs<types::Double>();
193         if (current->getSize() != 1)
194         {
195             return false;
196         }
197
198         ScicosID adaptee = adaptor.getAdaptee()->id();
199
200         std::vector<double> tol;
201         controller.getObjectProperty(adaptee, DIAGRAM, PROPERTIES, tol);
202
203         tol[0] = current->get(0);
204
205         controller.setObjectProperty(adaptee, DIAGRAM, PROPERTIES, tol);
206         return true;
207     }
208 };
209
210 struct context
211 {
212
213     static types::InternalType* get(const ParamsAdapter& adaptor, const Controller& controller)
214     {
215         ScicosID adaptee = adaptor.getAdaptee()->id();
216
217         std::vector<std::string> context;
218         controller.getObjectProperty(adaptee, DIAGRAM, DIAGRAM_CONTEXT, context);
219
220         if (context.size() == 0)
221         {
222             // An empty context returns an empty matrix
223             return types::Double::Empty();
224         }
225
226         types::String* o = new types::String((int)context.size(), 1);
227         for (int i = 0; i < (int)context.size(); ++i)
228         {
229             o->set(i, context[i].data());
230         }
231
232         return o;
233     }
234
235     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& controller)
236     {
237         if (v->getType() == types::InternalType::ScilabString)
238         {
239             types::String* current = v->getAs<types::String>();
240             // Only allow vectors and empty matrices
241             if (!current->isVector() && current->getSize() != 0)
242             {
243                 return false;
244             }
245
246             ScicosID adaptee = adaptor.getAdaptee()->id();
247
248             std::vector<std::string> context (current->getSize());
249             for (int i = 0; i < (int)context.size(); ++i)
250             {
251                 char* c_str = wide_string_to_UTF8(current->get(i));
252                 context[i] = std::string(c_str);
253                 FREE(c_str);
254             }
255
256             controller.setObjectProperty(adaptee, DIAGRAM, DIAGRAM_CONTEXT, context);
257             return true;
258         }
259         else if (v->getType() == types::InternalType::ScilabDouble)
260         {
261             types::Double* current = v->getAs<types::Double>();
262             if (!current->isEmpty())
263             {
264                 return false;
265             }
266
267             ScicosID adaptee = adaptor.getAdaptee()->id();
268
269             std::vector<std::string> context;
270             controller.setObjectProperty(adaptee, DIAGRAM, DIAGRAM_CONTEXT, context);
271             return true;
272         }
273         return false;
274     }
275 };
276
277 struct options
278 {
279
280     static types::InternalType* get(const ParamsAdapter& /*adaptor*/, const Controller& /*controller*/)
281     {
282         // Return a default 'scsopt'-typed tlist.
283         types::String* header = new types::String(1, 6);
284         header->set(0, scsopt.c_str());
285         header->set(1, ThreeD.c_str());
286         header->set(2, Background.c_str());
287         header->set(3, Link.c_str());
288         header->set(4, ID.c_str());
289         header->set(5, Cmap.c_str());
290
291         types::TList* Scsopt = new types::TList();
292         Scsopt->append(header);
293
294         types::List* ThreeDField = new types::List();
295         types::Bool* ThreeD1 = new types::Bool(1);
296         ThreeDField->append(ThreeD1);
297         types::Double* ThreeD2 = new types::Double(33);
298         ThreeDField->append(ThreeD2);
299         Scsopt->append(ThreeDField);
300
301         types::Double* BackgroundField = new types::Double(1, 2);
302         BackgroundField->set(0, 8);
303         BackgroundField->set(1, 1);
304         Scsopt->append(BackgroundField);
305
306         types::Double* LinkField = new types::Double(1, 2);
307         LinkField->set(0, 1);
308         LinkField->set(1, 5);
309         Scsopt->append(LinkField);
310
311         types::List* IDField = new types::List();
312         types::Double* ID1 = new types::Double(1, 4);
313         ID1->set(0, 4);
314         ID1->set(1, 1);
315         ID1->set(2, 10);
316         ID1->set(3, 1);
317         IDField->append(ID1);
318         types::Double* ID2 = new types::Double(1, 4);
319         ID2->set(0, 4);
320         ID2->set(1, 1);
321         ID2->set(2, 2);
322         ID2->set(3, 1);
323         IDField->append(ID2);
324         Scsopt->append(IDField);
325
326         types::Double* CmapField = new types::Double(1, 3);
327         CmapField->set(0, 0.8);
328         CmapField->set(1, 0.8);
329         CmapField->set(2, 0.8);
330         Scsopt->append(CmapField);
331
332         return Scsopt;
333     }
334
335     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& controller)
336     {
337         // The model does not store 'options'.
338         return dummy_property::set(adaptor, v, controller);
339     }
340 };
341
342 struct doc
343 {
344     static types::InternalType* get(const ParamsAdapter& adaptor, const Controller& /*controller*/)
345     {
346         return adaptor.getDocContent();
347     }
348
349     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& /*controller*/)
350     {
351         adaptor.setDocContent(v->clone());
352         return true;
353     }
354 };
355
356 } /* namespace */
357
358 template<> property<ParamsAdapter>::props_t property<ParamsAdapter>::fields = property<ParamsAdapter>::props_t();
359 static void initialize_fields()
360 {
361     if (property<ParamsAdapter>::properties_have_not_been_set())
362     {
363         property<ParamsAdapter>::fields.reserve(10);
364         property<ParamsAdapter>::add_property(L"wpar", &dummy_property::get, &dummy_property::set);
365         property<ParamsAdapter>::add_property(L"title", &title::get, &title::set);
366         property<ParamsAdapter>::add_property(L"tol", &tol::get, &tol::set);
367         property<ParamsAdapter>::add_property(L"tf", &tf::get, &tf::set);
368         property<ParamsAdapter>::add_property(L"context", &context::get, &context::set);
369         property<ParamsAdapter>::add_property(L"void1", &dummy_property::get, &dummy_property::set);
370         property<ParamsAdapter>::add_property(L"options", &options::get, &options::set);
371         property<ParamsAdapter>::add_property(L"void2", &dummy_property::get, &dummy_property::set);
372         property<ParamsAdapter>::add_property(L"void3", &dummy_property::get, &dummy_property::set);
373         property<ParamsAdapter>::add_property(L"doc", &doc::get, &doc::set);
374     }
375 }
376
377 ParamsAdapter::ParamsAdapter() :
378     BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::Diagram>(),
379     doc_content(new types::List())
380 {
381     initialize_fields();
382 }
383
384 ParamsAdapter::ParamsAdapter(const Controller& c, org_scilab_modules_scicos::model::Diagram* adaptee) :
385     BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::Diagram>(c, adaptee),
386     doc_content(new types::List())
387 {
388     initialize_fields();
389 }
390
391 ParamsAdapter::~ParamsAdapter()
392 {
393     doc_content->DecreaseRef();
394     doc_content->killMe();
395 }
396
397 std::wstring ParamsAdapter::getTypeStr()
398 {
399     return getSharedTypeStr();
400 }
401 std::wstring ParamsAdapter::getShortTypeStr()
402 {
403     return getSharedTypeStr();
404 }
405
406 types::InternalType* ParamsAdapter::getDocContent() const
407 {
408     doc_content->IncreaseRef();
409     return doc_content;
410 }
411
412 void ParamsAdapter::setDocContent(types::InternalType* v)
413 {
414     doc_content->DecreaseRef();
415     doc_content->killMe();
416
417     v->IncreaseRef();
418     doc_content = v;
419 }
420
421 } /* namespace view_scilab */
422 } /* namespace org_scilab_modules_scicos */