repos
/
qt.gui
/ annotate_shade
summary
|
shortlog
|
log
|
tree
|
commit
|
commitdiff
|
headdiff
|
annotate
|
filehistory
normal
|
plain
|
shade
|
zebra
Break API compatibility for qt:with-app and qt:exec & spellcheck
Annotate for file src/signal-slot/connect.lisp
2010-01-10 tobias
1
(in-package :cl-smoke.qt-impl)
08:52:49 '
2
'
3
(defgeneric qt:connect (qsignal slot &optional type)
'
4
(:documentation "Connects a signal to a slot."))
'
5
'
6
(defgeneric qt:disconnect (qsignal slot)
'
7
(:documentation "Disconnects a connection."))
'
8
'
9
(defgeneric qt:disconnect-all (qsignal)
'
10
(:documentation "Disconnects all connections of QSIGNAL."))
'
11
'
12
(defun check-argument-types (signal-arguments slot-arguments)
'
13
(assert (= (length signal-arguments) (length slot-arguments)))
'
14
(loop for signal-arg in signal-arguments
'
15
for slot-arg in slot-arguments do
2009-08-02 tobias
16
(assert (subtypep signal-arg slot-arg))))
2010-01-10 tobias
17
08:52:49 '
18
;;FIXME check argument-types
'
19
(defmethod qt:connect ((qsignal qsignal) (qslot qslot) &optional type)
'
20
(assert (or (slot-boundp (signal-object qsignal) 'argument-types)
'
21
(slot-boundp qslot 'arguments))
'
22
((slot-value (signal-object qsignal) 'argument-types)
'
23
(slot-value qslot 'arguments))
'
24
"Argument types must be specified for at least on of
'
25
~A and ~A." qsignal qslot)
'
26
(when (not (slot-boundp (signal-object qsignal) 'argument-types))
'
27
(setf (argument-types (signal-object qsignal))
'
28
(arguments qslot)))
'
29
(when (not (slot-boundp qslot 'arguments))
'
30
(setf (slot-value qslot 'arguments)
'
31
(argument-types (signal-object qsignal))))
'
32
(check-argument-types (argument-types (signal-object qsignal))
'
33
(arguments qslot))
'
34
(unless (connect-id (signal-object qsignal) (id (signal-object qsignal))
'
35
qslot (id qslot)
'
36
type
'
37
(types (arguments qslot)))
'
38
(cerror "Failed to connect ~S to ~S." qsignal qslot)))
'
39
'
40
(defmethod qt:connect ((sender qsignal) (function function) &optional type)
'
41
(let ((slot (make-instance 'qslot
2009-08-02 tobias
42
:args (list (signal-object sender))
2010-01-10 tobias
43
:argument-types (argument-types (signal-object sender))
08:52:49 '
44
:slot-function function)))
'
45
(unless (connect-id (signal-object sender) (id (signal-object sender))
'
46
slot (id slot)
'
47
type
'
48
(types (argument-types (signal-object sender))))
'
49
(cerror "Failed to connect the function ~S to the signal ~S."
'
50
function sender))))
'
51
'
52
(defclass qt-signal-slot-name ()
'
53
((name :initarg :name
'
54
:reader name)))
'
55
'
56
(defclass qt-signal (qt-signal-slot-name)
'
57
((sender :initarg :sender
'
58
:reader qsender))
'
59
(:documentation "Qt C++ signal."))
'
60
'
61
(defclass qt-slot (qt-signal-slot-name)
'
62
((receiver :initarg :receiver
'
63
:reader receiver))
'
64
(:documentation "Qt C++ slot."))
'
65
'
66
(defgeneric qt:get-slot (receiver name)
'
67
(:documentation "Returns the slot of RECEIVER with NAME.")
'
68
(:method (receiver name)
'
69
(make-instance 'qt-slot :receiver receiver :name name))
'
70
(:method (receiver (function function))
'
71
"Returns a slot for RECEIVER that calls function
'
72
with RECEIVER as the first argument."
2009-08-02 tobias
73
(let ((slot (qt:make-slot #'(lambda (&rest args)
11:15:21 '
74
(apply function (cxx:parent *this*)
'
75
args)))))
'
76
(cxx:set-parent slot receiver)
'
77
slot)))
2010-01-10 tobias
78
08:52:49 '
79
(define-compiler-macro qt:get-slot (&whole form receiver name)
'
80
"Normalize the slot name."
'
81
(if (stringp name)
'
82
(let ((normalized-name (cxx:data
'
83
(qt:meta-object.normalized-signature name))))
2009-08-02 tobias
84
(if (string= name normalized-name) ;; Avoid loop
2010-01-10 tobias
85
form
08:52:49 '
86
`(qt:get-slot ,receiver ,normalized-name)))
'
87
form))
'
88
'
89
(defun qt:get-signal (sender name)
'
90
"Returns the signal NAME of SENDER."
'
91
(make-instance 'qt-signal :sender sender :name name))
'
92
'
93
(define-compiler-macro qt:get-signal (&whole form sender name)
'
94
"Normalize the signal name."
'
95
(if (stringp name)
'
96
(let ((normalized-name (cxx:data
'
97
(qt:meta-object.normalized-signature name))))
2009-08-02 tobias
98
(if (string= name normalized-name) ;; Avoid loop
2010-01-10 tobias
99
form
08:52:49 '
100
`(qt:get-signal ,sender ,normalized-name)))
'
101
form))
'
102
'
103
(defmethod qt:connect ((qt-signal qt-signal) (qt-slot qt-slot) &optional type)
'
104
(unless (qt:object.connect (qsender qt-signal) (qt:qsignal (name qt-signal))
'
105
(receiver qt-slot) (qt:qslot (name qt-slot))
2009-08-27 tobias
106
(or type qt:+auto-connection+))
2010-01-10 tobias
107
(cerror "Failed to connect ~A ~A to ~A ~A."
08:52:49 '
108
(qsender qt-signal) (name qt-signal)
'
109
(receiver qt-slot) (name qt-slot))))
'
110
'
111
(defmethod qt:disconnect ((qt-signal qt-signal) (qt-slot qt-slot))
'
112
(unless (qt:object.disconnect (qsender qt-signal) (qt:qsignal (name qt-signal))
'
113
(receiver qt-slot) (qt:qslot (name qt-slot)))
'
114
(cerror "Failed to disconnect ~A ~A from ~A ~A."
'
115
(receiver qt-slot) (name qt-slot)
'
116
(qsender qt-signal) (name qt-signal))))
'
117
'
118
(defmethod qt:disconnect-all ((sender qt:object))
'
119
(unless (qt:object.disconnect sender 0 0 0)
'
120
(cerror "Failed to disconnect everything connected to ~A."
'
121
sender)))
'
122
'
123
'
124
(defmethod qt:connect ((qt-signal qt-signal) (function function) &optional type)
'
125
(let* ((signal-id (find-signal-id (qsender qt-signal) (name qt-signal)))
'
126
(slot (make-instance 'qslot
2009-07-27 tobias
127
;; Set the sender as the slots parent,
19:39:43 '
128
;; to ensure it does not get gc'ed.
2009-07-22 tobias
129
;; FIXME: unset parent on disconnect
2009-07-01 tobias
130
;; this no not critical because the slot object
2009-07-22 tobias
131
;; is hidden from the user, who thus can not
22:21:01 '
132
;; connect it to other signals.
2009-07-27 tobias
133
:args (list (qsender qt-signal))
2010-01-10 tobias
134
:slot-function function
08:52:49 '
135
:argument-types
'
136
(method-arguments-type
'
137
(cxx:meta-object (qsender qt-signal))
'
138
signal-id))))
'
139
(if (connect-id (qsender qt-signal) signal-id
'
140
slot (id slot)
'
141
type (types (arguments slot)))
'
142
(cxx:connect-notify (qsender qt-signal)
'
143
(name qt-signal))
'
144
(cerror "Ignore" "Failed to connect the signal ~S of ~S to the function ~S."
'
145
(name qt-signal) (qsender qt-signal) function))))
'
146
'
147
(defmethod qt:connect ((qt-signal qt-signal) (slot qslot) &optional type)
'
148
(let ((signal-id (find-signal-id (qsender qt-signal) (name qt-signal))))
'
149
(if (slot-boundp slot 'arguments)
'
150
(check-argument-types (method-arguments-type (cxx:meta-object
'
151
(qsender qt-signal))
'
152
signal-id)
'
153
(arguments slot))
'
154
(setf (slot-value slot 'arguments)
'
155
(method-arguments-type (cxx:meta-object (qsender qt-signal))
'
156
signal-id)))
'
157
(if (connect-id (qsender qt-signal) signal-id
'
158
slot (id slot)
'
159
type (types (arguments slot)))
'
160
(cxx:connect-notify (qsender qt-signal)
'
161
(name qt-signal))
'
162
(cerror "Ignore" "Failed to connect the signal ~S of ~S to the slot ~S."
'
163
(name qt-signal) (qsender qt-signal) slot))))
'
164
'
165
(defmethod qt:connect ((qsignal qsignal) (slot qt-slot) &optional type)
'
166
(let ((slot-id (find-slot-id (receiver slot) (name slot))))
'
167
(if (slot-boundp (signal-object qsignal) 'argument-types)
'
168
(check-argument-types (argument-types (signal-object slot))
'
169
(method-arguments-type (cxx:meta-object
'
170
(receiver slot))
'
171
slot-id))
'
172
(setf (argument-types (signal-object qsignal))
'
173
(method-arguments-type (cxx:meta-object (receiver slot))
'
174
slot-id)))
'
175
(unless (connect-id (signal-object qsignal) (id (signal-object qsignal))
'
176
(receiver slot) slot-id
'
177
type
'
178
(types (argument-types (signal-object qsignal))))
'
179
(cerror "Failed to connect ~S to ~S." qsignal slot))))
'
180
'
181
'
182
(defun connect-id (sender signal-id receiver slot-id type types)
'
183
(qt:meta-object.connect sender signal-id
'
184
receiver slot-id
'
185
(if (null type)
2009-08-27 tobias
186
(value qt:+auto-connection+)
08:37:36 '
187
(value type))
2010-01-10 tobias
188
types))
08:52:49 '
189
'
190
(defun disconnect-id (sender signal-id receiver slot-id)
'
191
(qt:meta-object.disconnect sender signal-id receiver slot-id))