Xcos MVC & GUI: allow to clone naked blocks (no ports)
[scilab.git] / scilab / modules / scicos / includes / Controller.hxx
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 #ifndef CONTROLLER_HXX_
14 #define CONTROLLER_HXX_
15
16 #include <string>
17 #include <vector>
18 #include <map>
19
20 #include "utilities.hxx"
21 #include "Model.hxx"
22 #include "View.hxx"
23
24 #include "dynlib_scicos.h"
25
26 namespace org_scilab_modules_scicos
27 {
28
29 /**
30  * Controller from the MVC pattern
31  *
32  * All calls to objects should use this controller, all usable objects are referenced by this controller.
33  */
34 class SCICOS_IMPEXP Controller
35 {
36 public:
37     static View* register_view(const std::string& name, View* v);
38     static void unregister_view(View* v);
39     static View* unregister_view(const std::string& name);
40     static View* look_for_view(const std::string& name);
41
42     Controller();
43     ~Controller();
44
45     ScicosID createObject(kind_t k);
46     unsigned referenceObject(const ScicosID uid) const;
47     template<typename T>
48     T* referenceObject(T* o) const
49     {
50         referenceObject(o->id());
51         return o;
52     }
53     void deleteObject(ScicosID uid);
54     ScicosID cloneObject(ScicosID uid, bool cloneChildren, bool clonePorts);
55
56     kind_t getKind(ScicosID uid) const;
57     std::vector<ScicosID> getAll(kind_t k) const;
58     model::BaseObject* getObject(ScicosID uid) const;
59     template<typename T>
60     T* getObject(ScicosID uid) const
61     {
62         return static_cast<T*>(getObject(uid));
63     }
64
65     template<typename T>
66     bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, T& v) const
67     {
68         return m_instance.model.getObjectProperty(uid, k, p, v);
69     };
70
71     template<typename T>
72     update_status_t setObjectProperty(const ScicosID& uid, kind_t k, object_properties_t p, T v)
73     {
74         update_status_t status = m_instance.model.setObjectProperty(uid, k, p, v);
75         for (view_set_t::iterator iter = m_instance.allViews.begin(); iter != m_instance.allViews.end(); ++iter)
76         {
77             (*iter)->propertyUpdated(uid, k, p, status);
78         }
79         return status;
80     }
81
82 private:
83
84     typedef std::vector<View*> view_set_t;
85     typedef std::vector<std::string> view_name_set_t;
86
87     /**
88      * Shared data through all instance of the controllers
89      */
90     struct SharedData
91     {
92         Model model;
93         view_name_set_t allNamedViews;
94         view_set_t allViews;
95
96         SharedData();
97         ~SharedData();
98     };
99
100     /**
101      * Shared instance of the data
102      *
103      * This will be allocated on-demand be Controller::get_instance()
104      */
105     static SharedData m_instance;
106
107     /*
108      * Methods
109      */
110
111     ScicosID cloneObject(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, bool cloneChildren, bool clonePorts);
112
113     template<typename T>
114     void cloneProperties(model::BaseObject* initial, ScicosID clone)
115     {
116         for (int i = 0; i < MAX_OBJECT_PROPERTIES; ++i)
117         {
118             enum object_properties_t p = static_cast<enum object_properties_t>(i);
119
120             T value;
121             bool status = getObjectProperty(initial->id(), initial->kind(), p, value);
122             if (status)
123             {
124                 setObjectProperty(clone, initial->kind(), p, value);
125             }
126         }
127
128     };
129
130     void deepClone(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, ScicosID clone, kind_t k, object_properties_t p, bool cloneIfNotFound);
131     void deepCloneVector(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, ScicosID clone, kind_t k, object_properties_t p, bool cloneIfNotFound);
132     void unlinkVector(ScicosID uid, kind_t k, object_properties_t uid_prop, object_properties_t ref_prop);
133     void unlink(ScicosID uid, kind_t k, object_properties_t uid_prop, object_properties_t ref_prop);
134     void deleteVector(ScicosID uid, kind_t k, object_properties_t uid_prop);
135 };
136
137 } /* namespace org_scilab_modules_scicos */
138
139 #endif /* CONTROLLER_HXX_ */