/ src /
/src/properties.lisp
1 (in-package :cl-smoke.qt.core)
2
3 (defun reverse-lispify (symbol)
4 "Converts the name of symbol to C++ style."
5 (if (eq (symbol-package symbol)
6 (find-package :keyword))
7 (smoke::lisp-to-cxx (symbol-name symbol))
8 (concatenate 'string
9 (package-name (symbol-package symbol))
10 "::"
11 (symbol-name symbol))))
12
13 (defun property-package (name)
14 (let ((package-end (search "::" name)))
15 (if package-end
16 (values
17 (find-package (intern (subseq name 0 package-end) :keyword))
18 (+ 2 package-end))
19 (values (find-package :keyword) 0))))
20
21 (defun lispify-property-name (name)
22 (multiple-value-bind (package name-start)
23 (property-package name)
24 (if (= 0 name-start)
25 (smoke::lispify name package)
26 (intern (subseq name name-start) package))))
27
28 (defun property-name (name)
29 "The property name is a string or a to camelCase converted symbol."
30 (typecase name
31 (string name)
32 (symbol (reverse-lispify name))))
33
34 (defun qt:property (object name)
35 "Returns the property NAME of OBJECT."
36 (declare (type qt:object object)
37 (type (or string symbol) name))
38 (assert (qt:property-p object name)
39 (object name)
40 "~A has no property ~A." object name)
41 (qt:from-variant (cxx:property object (property-name name))))
42
43 (defun (setf qt:property) (new-value object name)
44 (declare (type qt:object object)
45 (type (or string symbol) name))
46 (cxx:set-property object (property-name name)
47 (make-instance 'qt:variant :arg0 new-value))
48 new-value)
49
50 (defun qt:remove-property (object name)
51 "Removes the property NAME from OBJECT."
52 (declare (type qt:object object)
53 (type (or string symbol) name))
54 (setf (qt:property object name) (qt:make-variant)))
55
56 (defun qt:property-p (object name)
57 "Returns T when NAME is a property of OBJECT and NIL otherwise."
58 (declare (type qt:object object)
59 (type (or string symbol) name))
60 (qt:variant-boundp (cxx:property object (property-name name))))
61
62 (defun meta-object-properties (meta-object &optional (all t))
63 "Returns a list of the properties of META-OBJECT."
64 (loop for index from (if all 0 (cxx:property-offset meta-object))
65 below (cxx:property-count meta-object)
66 collect (lispify-property-name (cxx:name (cxx:property meta-object index)))))
67
68 (defun sort-symbols (symbols)
69 (sort symbols
70 #'(lambda (a b)
71 (string<= (write-to-string a) (write-to-string b)))))
72
73 (defgeneric qt:class-properties (class)
74 (:documentation "Returns a list of the properties of CLASS.")
75 (:method ((class class))
76 (sort-symbols
77 (meta-object-properties (cxx:static-meta-object class))))
78 (:method ((symbol symbol))
79 (qt:class-properties (find-class symbol))))
80
81 (defgeneric qt:class-direct-properties (class)
82 (:documentation "Returns a list of the properties of CLASS.")
83 (:method ((class class))
84 (meta-object-properties (cxx:static-meta-object class) nil))
85 (:method ((symbol symbol))
86 (qt:class-direct-properties (find-class symbol))))
87
88 (defun dynamic-properties (object)
89 (map 'list (compose #'lispify-property-name #'cxx:data)
90 (cxx:dynamic-property-names object)))
91
92 (defun qt:properties (object)
93 "Returns a list of the properties of OBJECT."
94 (declare (type qt:object object))
95 (sort-symbols
96 (nconc (dynamic-properties object)
97 (meta-object-properties (cxx:meta-object object)))))