* Bug 16365 fixed: median(m,'r'|'c') was wrong after 5dc990
[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-2016 - Scilab Enterprises - Clement DAVID
4  *  Copyright (C) 2017 - ESI Group - Clement DAVID
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 #include <cwchar>
18
19 #include <string>
20 #include <vector>
21
22 #include "internal.hxx"
23 #include "list.hxx"
24 #include "mlist.hxx"
25 #include "string.hxx"
26 #include "types.hxx"
27
28 #include "utilities.hxx"
29 #include "adapters_utilities.hxx"
30 #include "Controller.hxx"
31 #include "model/BaseObject.hxx"
32 #include "model/Block.hxx"
33 #include "BlockAdapter.hxx"
34 #include "DiagramAdapter.hxx"
35 #include "GraphicsAdapter.hxx"
36 #include "LinkAdapter.hxx"
37 #include "ModelAdapter.hxx"
38 #include "TextAdapter.hxx"
39
40 extern "C" {
41 #include "sci_malloc.h"
42 #include "charEncoding.h"
43 }
44
45 namespace org_scilab_modules_scicos
46 {
47 namespace view_scilab
48 {
49 namespace
50 {
51
52 struct graphics
53 {
54     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
55     {
56         GraphicsAdapter localAdaptor(controller, controller.referenceBaseObject(adaptor.getAdaptee()));
57         return localAdaptor.getAsTList(new types::MList(), controller);
58     }
59
60     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
61     {
62         GraphicsAdapter localAdaptor(controller, controller.referenceBaseObject(adaptor.getAdaptee()));
63         return localAdaptor.setAsTList(v, controller);
64     }
65 };
66
67 struct model
68 {
69     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
70     {
71         ModelAdapter localAdaptor(controller, controller.referenceBaseObject(adaptor.getAdaptee()));
72         return localAdaptor.getAsTList(new types::MList(), controller);
73     }
74
75     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
76     {
77         ModelAdapter localAdaptor(controller, controller.referenceBaseObject(adaptor.getAdaptee()));
78         return localAdaptor.setAsTList(v, controller);
79     }
80 };
81
82 struct gui
83 {
84     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
85     {
86         std::string Interface;
87         controller.getObjectProperty(adaptor.getAdaptee(), INTERFACE_FUNCTION, Interface);
88
89         return new types::String(Interface.data());
90     }
91
92     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
93     {
94         if (v->getType() != types::InternalType::ScilabString)
95         {
96             return false;
97         }
98
99         types::String* current = v->getAs<types::String>();
100         if (!current->isScalar())
101         {
102             return false;
103         }
104
105         wchar_t* w_name = current->get(0);
106         char* name = wide_string_to_UTF8(w_name);
107         std::string stName(name);
108         FREE(name);
109
110         controller.setObjectProperty(adaptor.getAdaptee(), INTERFACE_FUNCTION, stName);
111         return true;
112     }
113 };
114
115 struct doc
116 {
117     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& /*controller*/)
118     {
119         return adaptor.getDocContent();
120     }
121
122     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& /*controller*/)
123     {
124         adaptor.setDocContent(v->clone());
125         return true;
126     }
127 };
128
129 link_indices_t getPortEnd(const Controller& controller, org_scilab_modules_scicos::model::Block* adaptee, portKind port)
130 {
131     ScicosID parent;
132     kind_t parentKind = BLOCK;
133     controller.getObjectProperty(adaptee, PARENT_BLOCK, parent);
134     if (parent == ScicosID())
135     {
136         parentKind = DIAGRAM;
137         controller.getObjectProperty(adaptee, PARENT_DIAGRAM, parent);
138     }
139
140     // early return if this block is out of a hierarchy
141     if (parent == ScicosID())
142     {
143         return link_indices_t();
144     }
145
146     org_scilab_modules_scicos::model::BaseObject* parentObject = controller.getBaseObject(parent);
147
148     std::vector<ScicosID> children;
149     controller.getObjectProperty(parentObject, CHILDREN, children);
150
151     std::vector<ScicosID> ports;
152     controller.getObjectProperty(parentObject, property_from_port(port), children);
153
154     // store the index of the connected signal, 0 if absent
155     link_indices_t portIndices(ports.size());
156     for (size_t i = 0; i < ports.size(); ++i)
157     {
158         ScicosID signal;
159         controller.getObjectProperty(ports[i], PORT, CONNECTED_SIGNALS, signal);
160
161         if (signal != ScicosID())
162         {
163             auto it = std::find(children.begin(), children.end(), signal);
164             if (it != children.end())
165             {
166                 portIndices[i] = (int)std::distance(children.begin(), it);
167             }
168         }
169     }
170
171     return portIndices;
172 };
173
174 } /* namespace */
175
176 #ifndef _MSC_VER
177 template<>
178 #endif
179 property<BlockAdapter>::props_t property<BlockAdapter>::fields = property<BlockAdapter>::props_t();
180
181 BlockAdapter::BlockAdapter(const Controller& c, org_scilab_modules_scicos::model::Block* adaptee) :
182     BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
183     doc_content(default_value<types::List>())
184 {
185     if (property<BlockAdapter>::properties_have_not_been_set())
186     {
187         property<BlockAdapter>::reserve_properties(4);
188         property<BlockAdapter>::add_property(L"graphics", &graphics::get, &graphics::set);
189         property<BlockAdapter>::add_property(L"model", &model::get, &model::set);
190         property<BlockAdapter>::add_property(L"gui", &gui::get, &gui::set);
191         property<BlockAdapter>::add_property(L"doc", &doc::get, &doc::set);
192         property<BlockAdapter>::shrink_to_fit();
193     }
194 }
195
196 BlockAdapter::BlockAdapter(const BlockAdapter& adapter) :
197     BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(adapter),
198     doc_content(reference_value(adapter.doc_content))
199 {
200 }
201
202 BlockAdapter::~BlockAdapter()
203 {
204     doc_content->DecreaseRef();
205     doc_content->killMe();
206 }
207
208 std::wstring BlockAdapter::getTypeStr() const
209 {
210     return getSharedTypeStr();
211 }
212
213 std::wstring BlockAdapter::getShortTypeStr() const
214 {
215     return getSharedTypeStr();
216 }
217
218 types::InternalType* BlockAdapter::getDocContent() const
219 {
220     return doc_content;
221 }
222
223 void BlockAdapter::setDocContent(types::InternalType* v)
224 {
225     types::InternalType* temp = doc_content;
226
227     // Do not check if v is nullptr on purpose ; it *should* not
228     v->IncreaseRef();
229     doc_content = v;
230
231     temp->DecreaseRef();
232     temp->killMe();
233 }
234
235 } /* namespace view_scilab */
236 } /* namespace org_scilab_modules_scicos */