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