1 /************************************************************************
2  *
3  * Copyright 2010 - 2012 Jakob Leben (jakob.leben@gmail.com)
4  *
5  * This file is part of SuperCollider Qt GUI.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  ************************************************************************/
21 
22 #include "metatype.hpp"
23 #include "type_codec.hpp"
24 #include "Common.h" // Make sure PyrObject* is declared to QMetaType
25 #include <PyrKernel.h>
26 
27 #include "QcCallback.hpp"
28 
29 namespace QtCollider {
30 
31 static QVector<MetaType*> gMetaTypes;
32 
33 template <typename T> MetaTypeImpl<T>* MetaTypeImpl<T>::instance = 0;
34 
qc_init_metatype()35 template <typename T> void qc_init_metatype() {
36     MetaTypeImpl<T>::instance = new MetaTypeImpl<T>();
37     gMetaTypes.append(MetaTypeImpl<T>::instance);
38 }
39 
initAll()40 void MetaType::initAll() {
41     qRegisterMetaType<PyrObject*>();
42     qRegisterMetaType<QObjectProxy*>();
43     qRegisterMetaType<QcTreeWidget::ItemPtr>();
44     qRegisterMetaType<QVector<double>>();
45     qRegisterMetaType<QVector<int>>();
46     qRegisterMetaType<SharedImage>();
47     qRegisterMetaType<QcAction*>();
48     qRegisterMetaType<QcWidgetAction*>();
49     qRegisterMetaType<QcMenu*>();
50     qRegisterMetaType<QcToolBar*>();
51     qRegisterMetaType<QList<QAction*>>();
52 
53     gMetaTypes.reserve(30);
54 
55     qc_init_metatype<bool>();
56     qc_init_metatype<int>();
57     qc_init_metatype<float>();
58     qc_init_metatype<double>();
59     qc_init_metatype<QChar>();
60     qc_init_metatype<QString>();
61     qc_init_metatype<QPointF>();
62     qc_init_metatype<QPoint>();
63     qc_init_metatype<QSizeF>();
64     qc_init_metatype<QSize>();
65     qc_init_metatype<QRectF>();
66     qc_init_metatype<QRect>();
67     qc_init_metatype<QColor>();
68     qc_init_metatype<QFont>();
69     qc_init_metatype<QPalette>();
70     qc_init_metatype<QObjectProxy*>();
71     qc_init_metatype<QObject*>();
72     qc_init_metatype<QWidget*>();
73     qc_init_metatype<QLayout*>();
74     qc_init_metatype<PyrObject*>();
75     qc_init_metatype<QcTreeWidget::ItemPtr>();
76     qc_init_metatype<SharedImage>();
77     qc_init_metatype<QMenu*>();
78     qc_init_metatype<QAction*>();
79     qc_init_metatype<QList<QAction*>>();
80     qc_init_metatype<QVector<double>>();
81     qc_init_metatype<QVector<int>>();
82     qc_init_metatype<QVariantList>();
83     qc_init_metatype<QUrl>();
84     qc_init_metatype<QcCallback*>();
85 }
86 
find(PyrSlot * slot)87 MetaType* MetaType::find(PyrSlot* slot) {
88     switch (GetTag(slot)) {
89     case tagNil:
90         return 0;
91     case tagInt:
92         return metaType<int>();
93     case tagSym:
94         return metaType<QString>();
95     case tagChar:
96         return metaType<QChar>();
97     case tagFalse:
98     case tagTrue:
99         return metaType<bool>();
100     case tagObj: {
101         PyrObject* obj = slotRawObject(slot);
102         PyrClass* klass = obj->classptr;
103         unsigned char format = obj->obj_format;
104 
105         if (format == obj_double || format == obj_float)
106             return metaType<QVector<double>>();
107 
108         else if (format == obj_int32 || format == obj_int16 || format == obj_int8)
109             return metaType<QVector<int>>();
110 
111         else if (isKindOfSlot(slot, class_string)) {
112             return metaType<QString>();
113         } else if (isKindOfSlot(slot, SC_CLASS(Point))) {
114             return metaType<QPointF>();
115         } else if (isKindOfSlot(slot, SC_CLASS(Rect))) {
116             return metaType<QRectF>();
117         } else if (isKindOfSlot(slot, SC_CLASS(Size))) {
118             return metaType<QSizeF>();
119         } else if (klass == SC_CLASS(Color) || klass == SC_CLASS(Gradient) || klass == SC_CLASS(HiliteGradient)) {
120             return metaType<QColor>();
121         } else if (isKindOfSlot(slot, SC_CLASS(Font))) {
122             return metaType<QFont>();
123         } else if (isKindOfSlot(slot, SC_CLASS(QPalette))) {
124             return metaType<QPalette>();
125         } else if (isKindOfSlot(slot, SC_CLASS(QCallback))) {
126             return metaType<QcCallback*>();
127         } else if (isKindOfSlot(slot, SC_CLASS(AbstractMenuAction))) {
128             return metaType<QAction*>();
129         } else if (isKindOfSlot(slot, SC_CLASS(Menu))) {
130             return metaType<QMenu*>();
131         } else if (isKindOfSlot(slot, SC_CLASS(View)) || isKindOfSlot(slot, SC_CLASS(ScrollCanvas))) {
132             return metaType<QWidget*>();
133         } else if (isKindOfSlot(slot, SC_CLASS(Layout))) {
134             return metaType<QLayout*>();
135         } else if (isKindOfSlot(slot, SC_CLASS(QObject))) {
136             return metaType<QObjectProxy*>();
137         } else if (isKindOfSlot(slot, class_array) || isKindOfSlot(slot, class_symbolarray)) {
138             return metaType<QVariantList>();
139         } else if (isKindOfSlot(slot, SC_CLASS(TreeViewItem))) {
140             return metaType<QcTreeWidget::ItemPtr>();
141         } else if (isKindOfSlot(slot, SC_CLASS(Image))) {
142             return metaType<SharedImage>();
143         } else {
144             QString className = TypeCodec<QString>::read(&slotRawObject(slot)->classptr->name);
145             qcWarningMsg(QStringLiteral("WARNING: Do not know how to use an instance of class '%1'").arg(className));
146             return 0;
147         }
148     }
149     default:
150         return metaType<double>();
151     }
152 }
153 
find(int id)154 MetaType* MetaType::find(int id) {
155     int n = gMetaTypes.count();
156     MetaType* const* d = gMetaTypes.constData();
157 
158     int i;
159     for (i = 0; i < n; ++i) {
160         if ((*d)->mId == id)
161             return *d;
162         ++d;
163     }
164 
165     return 0;
166 }
167 
168 } // namespace QtCollider
169