rb-scpt 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rb-scpt-1.0.1.gem +0 -0
  3. data/extconf.rb +12 -12
  4. data/rb-scpt.gemspec +10 -10
  5. data/sample/AB_export_vcard.rb +16 -16
  6. data/sample/AB_list_people_with_emails.rb +4 -4
  7. data/sample/Add_iCal_event.rb +12 -12
  8. data/sample/Create_daily_iCal_todos.rb +28 -28
  9. data/sample/Export_Address_Book_phone_numbers.rb +52 -52
  10. data/sample/Hello_world.rb +10 -10
  11. data/sample/List_iTunes_playlist_names.rb +3 -3
  12. data/sample/Make_Mail_message.rb +24 -24
  13. data/sample/Open_file_in_TextEdit.rb +5 -5
  14. data/sample/Organize_Mail_messages.rb +46 -46
  15. data/sample/Print_folder_tree.rb +5 -5
  16. data/sample/Select_all_HTML_files.rb +6 -6
  17. data/sample/Set_iChat_status.rb +12 -12
  18. data/sample/Simple_Finder_GUI_Scripting.rb +6 -6
  19. data/sample/Stagger_Finder_windows.rb +9 -9
  20. data/sample/TextEdit_demo.rb +71 -71
  21. data/sample/iTunes_top40_to_html.rb +28 -30
  22. data/src/SendThreadSafe.c +293 -293
  23. data/src/SendThreadSafe.h +108 -108
  24. data/src/lib/_aem/aemreference.rb +997 -998
  25. data/src/lib/_aem/codecs.rb +609 -610
  26. data/src/lib/_aem/connect.rb +197 -197
  27. data/src/lib/_aem/encodingsupport.rb +67 -67
  28. data/src/lib/_aem/findapp.rb +75 -75
  29. data/src/lib/_aem/mactypes.rb +241 -242
  30. data/src/lib/_aem/send.rb +268 -268
  31. data/src/lib/_aem/typewrappers.rb +52 -52
  32. data/src/lib/_appscript/defaultterminology.rb +266 -266
  33. data/src/lib/_appscript/referencerenderer.rb +230 -233
  34. data/src/lib/_appscript/reservedkeywords.rb +106 -106
  35. data/src/lib/_appscript/safeobject.rb +125 -125
  36. data/src/lib/_appscript/terminology.rb +448 -449
  37. data/src/lib/aem.rb +238 -238
  38. data/src/lib/kae.rb +1487 -1487
  39. data/src/lib/osax.rb +647 -647
  40. data/src/lib/rb-scpt.rb +1065 -1065
  41. data/src/rbae.c +595 -595
  42. data/test/test_aemreference.rb +104 -107
  43. data/test/test_appscriptcommands.rb +131 -134
  44. data/test/test_appscriptreference.rb +96 -99
  45. data/test/test_codecs.rb +166 -168
  46. data/test/test_findapp.rb +13 -16
  47. data/test/test_mactypes.rb +70 -72
  48. data/test/test_osax.rb +46 -48
  49. data/test/testall.sh +4 -4
  50. metadata +8 -7
@@ -6,274 +6,274 @@
6
6
 
7
7
  module Send
8
8
 
9
- # Defines the Event class, which represents an Apple event that's packed and ready to send,
10
- # and the EventError class, which contains error information for a failed event.
9
+ # Defines the Event class, which represents an Apple event that's packed and ready to send,
10
+ # and the EventError class, which contains error information for a failed event.
11
11
 
12
- require "ae"
13
- require "kae"
14
- require "_aem/codecs"
15
-
16
- class Event
17
- # Represents an Apple event.
18
-
19
- # Clients don't instantiate this class directly; instead, new instances are returned by AEM::Application#event.
20
-
21
- attr_reader :AEM_event
22
-
23
- def initialize(address, event_code, params={}, atts={}, transaction=KAE::KAnyTransactionID,
24
- return_id= KAE::KAutoGenerateReturnID, codecs=DefaultCodecs)
25
- # Create and pack a new Apple event ready for sending.
26
- # address : AEAddressDesc -- the target application, identified by PSN, URL, etc.
27
- # event_code : string -- 8-letter code indicating event's class and id, e.g. 'coregetd'
28
- # params : hash -- a hash of form {AE_code=>anything,...} containing zero or more event parameters (message arguments)
29
- # atts : hash -- a hash of form {AE_code=>anything,...} containing zero or more event attributes (event info)
30
- # transaction : integer -- transaction number; AEM::Application takes care of this value
31
- # return_id : integer -- reply event's ID
32
- # codecs : Codecs -- clients can provide custom Codecs object for packing parameters and unpacking result of this event
33
- @_event_code = event_code
34
- @_codecs = codecs
35
- @AEM_event = _create_apple_event(event_code[0, 4], event_code[-4, 4], address, return_id, transaction)
36
- atts.each {|key, value| @AEM_event.put_attr(key, codecs.pack(value))}
37
- params.each {|key, value| @AEM_event.put_param(key, codecs.pack(value))}
38
- end
39
-
40
- def _create_apple_event(event_class, event_id, target, return_id, transaction_id)
41
- # Hook method; may be overridden to customise how AppleEvent descriptors are created.
42
- return AE::AEDesc.new_apple_event(event_class, event_id, target, return_id, transaction_id)
43
- end
44
-
45
- def _send_apple_event(flags, timeout)
46
- # Hook method; may be overridden to customise how events are sent.
47
- return @AEM_event.send_thread_safe(flags, timeout)
48
- end
49
-
50
- def inspect
51
- return "#<AEM::Event @code=#{@_event_code}>"
52
- end
53
-
54
- alias_method :to_s, :inspect
55
-
56
- def send(timeout=KAE::KAEDefaultTimeout, flags=KAE::KAECanSwitchLayer + KAE::KAEWaitReply)
57
- # Send this Apple event (may be called any number of times).
58
- # timeout : int | KAEDefaultTimeout | KNoTimeOut -- number of ticks to wait for target process to reply before raising timeout error
59
- # flags : integer -- bitwise flags [1] indicating how target process should handle event
60
- # Result : anything -- value returned by application, if any
61
- #
62
- # [1] Should be the sum of zero or more of the following kae module constants:
63
- #
64
- # KAENoReply | KAEQueueReply | KAEWaitReply
65
- # KAEDontReconnect
66
- # KAEWantReceipt
67
- # KAENeverInteract | KAECanInteract | KAEAlwaysInteract
68
- # KAECanSwitchLayer
12
+ require "ae"
13
+ require "kae"
14
+ require "_aem/codecs"
69
15
 
70
- begin
71
- reply_event = _send_apple_event(flags, timeout)
72
- rescue AE::MacOSError => err # The Apple Event Manager raised an error.
73
- if not(@_event_code == 'aevtquit' and err.to_i == -609) # Ignore invalid connection errors (-609) when quitting
74
- raise EventError.new(err.to_i)
75
- end
76
- else # Decode application's reply, if any. May be a return value, error number (and optional message), or nothing.
77
- if reply_event.type != KAE::TypeNull
78
- event_result = {}
79
- reply_event.length.times do |i|
80
- key, value = reply_event.get_item(i + 1, KAE::TypeWildCard)
81
- event_result[key] = value
82
- end
83
- if event_result.has_key?(KAE::KeyErrorNumber) # The application raised an error.
84
- # Error info is unpacked using default codecs for reliability.
85
- e_num = DefaultCodecs.unpack(event_result[KAE::KeyErrorNumber])
86
- if e_num != 0 # Some apps (e.g. Finder) may return error code 0 to indicate a successful operation, so ignore this.
87
- raise EventError.new(e_num, event_result)
88
- end
89
- end
90
- if event_result.has_key?(KAE::KeyAEResult)
91
- # Return values are unpacked using [optionally] client-supplied codecs.
92
- # This allows aem clients such as appscript to customise how values are unpacked
93
- # (e.g. to unpack object specifier descs as appscript references instead of aem references).
94
- return @_codecs.unpack(event_result[KAE::KeyAEResult])
95
- end
96
- end
97
- end
98
- end
99
- end
100
-
101
-
102
- class EventError < RuntimeError
103
- # Represents an error raised by the Apple Event Manager or target application when a command fails.
104
- #
105
- # Methods:
106
- # number : integer -- MacOS error number
107
- # message : string -- application error message if any, or default error description if available
108
-
109
- # Most applications don't provide error description strings, so define default descriptions for the common ones.
110
- # Following default error descriptions are cribbed from the AppleScript Language Guide/MacErrors.h:
111
-
112
- MacOSErrorDescriptions = {
113
- # OS errors
114
- -34 => "Disk is full.",
115
- -35 => "Disk wasn't found.",
116
- -37 => "Bad name for file.",
117
- -38 => "File wasn't open.",
118
- -39 => "End of file error.",
119
- -42 => "Too many files open.",
120
- -43 => "File wasn't found.",
121
- -44 => "Disk is write protected.",
122
- -45 => "File is locked.",
123
- -46 => "Disk is locked.",
124
- -47 => "File is busy.",
125
- -48 => "Duplicate file name.",
126
- -49 => "File is already open.",
127
- -50 => "Parameter error.",
128
- -51 => "File reference number error.",
129
- -61 => "File not open with write permission.",
130
- -108 => "Out of memory.",
131
- -120 => "Folder wasn't found.",
132
- -124 => "Disk is disconnected.",
133
- -128 => "User canceled.",
134
- -192 => "A resource wasn't found.",
135
- -600 => "Application isn't running.",
136
- -601 => "Not enough room to launch application with special requirements.",
137
- -602 => "Application is not 32-bit clean.",
138
- -605 => "More memory is needed than is specified in the size resource.",
139
- -606 => "Application is background-only.",
140
- -607 => "Buffer is too small.",
141
- -608 => "No outstanding high-level event.",
142
- -609 => "Connection is invalid.",
143
- -904 => "Not enough system memory to connect to remote application.",
144
- -905 => "Remote access is not allowed.",
145
- -906 => "Application isn't running or program linking isn't enabled.",
146
- -915 => "Can't find remote machine.",
147
- -30720 => "Invalid date and time.",
148
- # AE errors
149
- -1700 => "Can't make some data into the expected type.",
150
- -1701 => "Some parameter is missing for command.",
151
- -1702 => "Some data could not be read.",
152
- -1703 => "Some data was the wrong type.",
153
- -1704 => "Some parameter was invalid.",
154
- -1705 => "Operation involving a list item failed.",
155
- -1706 => "Need a newer version of the Apple Event Manager.",
156
- -1707 => "Event isn't an Apple event.",
157
- -1708 => "Application could not handle this command.",
158
- -1709 => "AEResetTimer was passed an invalid reply.",
159
- -1710 => "Invalid sending mode was passed.",
160
- -1711 => "User canceled out of wait loop for reply or receipt.",
161
- -1712 => "Apple event timed out.",
162
- -1713 => "No user interaction allowed.",
163
- -1714 => "Wrong keyword for a special function.",
164
- -1715 => "Some parameter wasn't understood.",
165
- -1716 => "Unknown Apple event address type.",
166
- -1717 => "The handler is not defined.",
167
- -1718 => "Reply has not yet arrived.",
168
- -1719 => "Can't get reference. Invalid index.",
169
- -1720 => "Invalid range.",
170
- -1721 => "Wrong number of parameters for command.",
171
- -1723 => "Can't get reference. Access not allowed.",
172
- -1725 => "Illegal logical operator called.",
173
- -1726 => "Illegal comparison or logical.",
174
- -1727 => "Expected a reference.",
175
- -1728 => "Can't get reference.",
176
- -1729 => "Object counting procedure returned a negative count.",
177
- -1730 => "Container specified was an empty list.",
178
- -1731 => "Unknown object type.",
179
- -1739 => "Attempting to perform an invalid operation on a null descriptor.",
180
- # Application scripting errors
181
- -10000 => "Apple event handler failed.",
182
- -10001 => "Type error.",
183
- -10002 => "Invalid key form.",
184
- -10003 => "Can't set reference to given value. Access not allowed.",
185
- -10004 => "A privilege violation occurred.",
186
- -10005 => "The read operation wasn't allowed.",
187
- -10006 => "Can't set reference to given value.",
188
- -10007 => "The index of the event is too large to be valid.",
189
- -10008 => "The specified object is a property, not an element.",
190
- -10009 => "Can't supply the requested descriptor type for the data.",
191
- -10010 => "The Apple event handler can't handle objects of this class.",
192
- -10011 => "Couldn't handle this command because it wasn't part of the current transaction.",
193
- -10012 => "The transaction to which this command belonged isn't a valid transaction.",
194
- -10013 => "There is no user selection.",
195
- -10014 => "Handler only handles single objects.",
196
- -10015 => "Can't undo the previous Apple event or user action.",
197
- -10023 => "Enumerated value is not allowed for this property.",
198
- -10024 => "Class can't be an element of container.",
199
- -10025 => "Illegal combination of properties settings.",
200
- }
201
-
202
- # Following Cocoa Scripting error descriptions taken from:
203
- # http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSScriptCommand.html
204
- # http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSScriptObjectSpecifier.html
205
-
206
- CocoaErrorDescriptions = [
207
- ["NSReceiverEvaluationScriptError", "The object or objects specified by the direct parameter to a command could not be found."],
208
- ["NSKeySpecifierEvaluationScriptError", "The object or objects specified by a key (for commands that support key specifiers) could not be found."],
209
- ["NSArgumentEvaluationScriptError", "The object specified by an argument could not be found."],
210
- ["NSReceiversCantHandleCommandScriptError", "The receivers don't support the command sent to them."],
211
- ["NSRequiredArgumentsMissingScriptError", "An argument (or more than one argument) is missing."],
212
- ["NSArgumentsWrongScriptError", "An argument (or more than one argument) is of the wrong type or is otherwise invalid."],
213
- ["NSUnknownKeyScriptError", "An unidentified error occurred; indicates an error in the scripting support of the application."],
214
- ["NSInternalScriptError", "An unidentified internal error occurred; indicates an error in the scripting support of the application."],
215
- ["NSOperationNotSupportedForKeyScriptError", "The implementation of a scripting command signaled an error."],
216
- ["NSCannotCreateScriptCommandError", "Could not create the script command; an invalid or unrecognized Apple event was received."],
217
- ["NSNoSpecifierError", "No error encountered."],
218
- ["NSNoTopLevelContainersSpecifierError", "Someone called evaluate with nil."],
219
- ["NSContainerSpecifierError", "Error evaluating container specifier."],
220
- ["NSUnknownKeySpecifierError", "Receivers do not understand the key."],
221
- ["NSInvalidIndexSpecifierError", "Index out of bounds."],
222
- ["NSInternalSpecifierError", "Other internal error."],
223
- ["NSOperationNotSupportedForKeySpecifierError", "Attempt made to perform an unsupported operation on some key."]
224
- ]
225
-
226
- attr_reader :number, :raw
227
- alias_method :to_i, :number
228
-
229
- def initialize(number, reply_params={})
230
- @number = number
231
- @message = nil
232
- @raw = reply_params
233
- end
234
-
235
- def message
236
- if not @message
237
- desc = @raw[KAE::KeyErrorString]
238
- @message = DefaultCodecs.unpack(desc) if desc
239
- if @message.is_a?(String) and @number > 0
240
- # add clarification to default Cocoa Scripting error messages
241
- CocoaErrorDescriptions.each do |name, description|
242
- if @message[0, name.length] == name
243
- @message += " (#{description})"
244
- break
245
- end
246
- end
247
- end
248
- # if no message supplied or is a MacOSError, use default message if one is available
249
- @message = MacOSErrorDescriptions.fetch(number, '') if @message == nil
250
- end
251
- return @message
252
- end
253
-
254
- def to_s
255
- if message != ''
256
- return "EventError\n\t\tOSERROR: #{number}\n\t\tMESSAGE: #{message}"
257
- else
258
- return "EventError\n\t\tOSERROR: #{number}"
259
- end
260
- end
261
-
262
- # extended error info (some apps may return additional error info, though most don't)
263
-
264
- def offending_object
265
- desc = @raw[KAE::KOSAErrorOffendingObject]
266
- return desc ? DefaultCodecs.unpack(desc) : nil
267
- end
268
-
269
- def expected_type
270
- desc = @raw[KAE::KOSAErrorExpectedType]
271
- return desc ? DefaultCodecs.unpack(desc) : nil
272
- end
273
-
274
- def partial_result
275
- desc = @raw[KAE::KOSAErrorPartialResult]
276
- return desc ? DefaultCodecs.unpack(desc) : nil
277
- end
278
- end
16
+ class Event
17
+ # Represents an Apple event.
18
+
19
+ # Clients don't instantiate this class directly; instead, new instances are returned by AEM::Application#event.
20
+
21
+ attr_reader :AEM_event
22
+
23
+ def initialize(address, event_code, params={}, atts={}, transaction=KAE::KAnyTransactionID,
24
+ return_id= KAE::KAutoGenerateReturnID, codecs=DefaultCodecs)
25
+ # Create and pack a new Apple event ready for sending.
26
+ # address : AEAddressDesc -- the target application, identified by PSN, URL, etc.
27
+ # event_code : string -- 8-letter code indicating event's class and id, e.g. 'coregetd'
28
+ # params : hash -- a hash of form {AE_code=>anything,...} containing zero or more event parameters (message arguments)
29
+ # atts : hash -- a hash of form {AE_code=>anything,...} containing zero or more event attributes (event info)
30
+ # transaction : integer -- transaction number; AEM::Application takes care of this value
31
+ # return_id : integer -- reply event's ID
32
+ # codecs : Codecs -- clients can provide custom Codecs object for packing parameters and unpacking result of this event
33
+ @_event_code = event_code
34
+ @_codecs = codecs
35
+ @AEM_event = _create_apple_event(event_code[0, 4], event_code[-4, 4], address, return_id, transaction)
36
+ atts.each {|key, value| @AEM_event.put_attr(key, codecs.pack(value))}
37
+ params.each {|key, value| @AEM_event.put_param(key, codecs.pack(value))}
38
+ end
39
+
40
+ def _create_apple_event(event_class, event_id, target, return_id, transaction_id)
41
+ # Hook method; may be overridden to customise how AppleEvent descriptors are created.
42
+ return AE::AEDesc.new_apple_event(event_class, event_id, target, return_id, transaction_id)
43
+ end
44
+
45
+ def _send_apple_event(flags, timeout)
46
+ # Hook method; may be overridden to customise how events are sent.
47
+ return @AEM_event.send_thread_safe(flags, timeout)
48
+ end
49
+
50
+ def inspect
51
+ return "#<AEM::Event @code=#{@_event_code}>"
52
+ end
53
+
54
+ alias_method :to_s, :inspect
55
+
56
+ def send(timeout=KAE::KAEDefaultTimeout, flags=KAE::KAECanSwitchLayer + KAE::KAEWaitReply)
57
+ # Send this Apple event (may be called any number of times).
58
+ # timeout : int | KAEDefaultTimeout | KNoTimeOut -- number of ticks to wait for target process to reply before raising timeout error
59
+ # flags : integer -- bitwise flags [1] indicating how target process should handle event
60
+ # Result : anything -- value returned by application, if any
61
+ #
62
+ # [1] Should be the sum of zero or more of the following kae module constants:
63
+ #
64
+ # KAENoReply | KAEQueueReply | KAEWaitReply
65
+ # KAEDontReconnect
66
+ # KAEWantReceipt
67
+ # KAENeverInteract | KAECanInteract | KAEAlwaysInteract
68
+ # KAECanSwitchLayer
69
+
70
+ begin
71
+ reply_event = _send_apple_event(flags, timeout)
72
+ rescue AE::MacOSError => err # The Apple Event Manager raised an error.
73
+ if not(@_event_code == 'aevtquit' and err.to_i == -609) # Ignore invalid connection errors (-609) when quitting
74
+ raise EventError.new(err.to_i)
75
+ end
76
+ else # Decode application's reply, if any. May be a return value, error number (and optional message), or nothing.
77
+ if reply_event.type != KAE::TypeNull
78
+ event_result = {}
79
+ reply_event.length.times do |i|
80
+ key, value = reply_event.get_item(i + 1, KAE::TypeWildCard)
81
+ event_result[key] = value
82
+ end
83
+ if event_result.has_key?(KAE::KeyErrorNumber) # The application raised an error.
84
+ # Error info is unpacked using default codecs for reliability.
85
+ e_num = DefaultCodecs.unpack(event_result[KAE::KeyErrorNumber])
86
+ if e_num != 0 # Some apps (e.g. Finder) may return error code 0 to indicate a successful operation, so ignore this.
87
+ raise EventError.new(e_num, event_result)
88
+ end
89
+ end
90
+ if event_result.has_key?(KAE::KeyAEResult)
91
+ # Return values are unpacked using [optionally] client-supplied codecs.
92
+ # This allows aem clients such as appscript to customise how values are unpacked
93
+ # (e.g. to unpack object specifier descs as appscript references instead of aem references).
94
+ return @_codecs.unpack(event_result[KAE::KeyAEResult])
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+
102
+ class EventError < RuntimeError
103
+ # Represents an error raised by the Apple Event Manager or target application when a command fails.
104
+ #
105
+ # Methods:
106
+ # number : integer -- MacOS error number
107
+ # message : string -- application error message if any, or default error description if available
108
+
109
+ # Most applications don't provide error description strings, so define default descriptions for the common ones.
110
+ # Following default error descriptions are cribbed from the AppleScript Language Guide/MacErrors.h:
111
+
112
+ MacOSErrorDescriptions = {
113
+ # OS errors
114
+ -34 => "Disk is full.",
115
+ -35 => "Disk wasn't found.",
116
+ -37 => "Bad name for file.",
117
+ -38 => "File wasn't open.",
118
+ -39 => "End of file error.",
119
+ -42 => "Too many files open.",
120
+ -43 => "File wasn't found.",
121
+ -44 => "Disk is write protected.",
122
+ -45 => "File is locked.",
123
+ -46 => "Disk is locked.",
124
+ -47 => "File is busy.",
125
+ -48 => "Duplicate file name.",
126
+ -49 => "File is already open.",
127
+ -50 => "Parameter error.",
128
+ -51 => "File reference number error.",
129
+ -61 => "File not open with write permission.",
130
+ -108 => "Out of memory.",
131
+ -120 => "Folder wasn't found.",
132
+ -124 => "Disk is disconnected.",
133
+ -128 => "User canceled.",
134
+ -192 => "A resource wasn't found.",
135
+ -600 => "Application isn't running.",
136
+ -601 => "Not enough room to launch application with special requirements.",
137
+ -602 => "Application is not 32-bit clean.",
138
+ -605 => "More memory is needed than is specified in the size resource.",
139
+ -606 => "Application is background-only.",
140
+ -607 => "Buffer is too small.",
141
+ -608 => "No outstanding high-level event.",
142
+ -609 => "Connection is invalid.",
143
+ -904 => "Not enough system memory to connect to remote application.",
144
+ -905 => "Remote access is not allowed.",
145
+ -906 => "Application isn't running or program linking isn't enabled.",
146
+ -915 => "Can't find remote machine.",
147
+ -30720 => "Invalid date and time.",
148
+ # AE errors
149
+ -1700 => "Can't make some data into the expected type.",
150
+ -1701 => "Some parameter is missing for command.",
151
+ -1702 => "Some data could not be read.",
152
+ -1703 => "Some data was the wrong type.",
153
+ -1704 => "Some parameter was invalid.",
154
+ -1705 => "Operation involving a list item failed.",
155
+ -1706 => "Need a newer version of the Apple Event Manager.",
156
+ -1707 => "Event isn't an Apple event.",
157
+ -1708 => "Application could not handle this command.",
158
+ -1709 => "AEResetTimer was passed an invalid reply.",
159
+ -1710 => "Invalid sending mode was passed.",
160
+ -1711 => "User canceled out of wait loop for reply or receipt.",
161
+ -1712 => "Apple event timed out.",
162
+ -1713 => "No user interaction allowed.",
163
+ -1714 => "Wrong keyword for a special function.",
164
+ -1715 => "Some parameter wasn't understood.",
165
+ -1716 => "Unknown Apple event address type.",
166
+ -1717 => "The handler is not defined.",
167
+ -1718 => "Reply has not yet arrived.",
168
+ -1719 => "Can't get reference. Invalid index.",
169
+ -1720 => "Invalid range.",
170
+ -1721 => "Wrong number of parameters for command.",
171
+ -1723 => "Can't get reference. Access not allowed.",
172
+ -1725 => "Illegal logical operator called.",
173
+ -1726 => "Illegal comparison or logical.",
174
+ -1727 => "Expected a reference.",
175
+ -1728 => "Can't get reference.",
176
+ -1729 => "Object counting procedure returned a negative count.",
177
+ -1730 => "Container specified was an empty list.",
178
+ -1731 => "Unknown object type.",
179
+ -1739 => "Attempting to perform an invalid operation on a null descriptor.",
180
+ # Application scripting errors
181
+ -10000 => "Apple event handler failed.",
182
+ -10001 => "Type error.",
183
+ -10002 => "Invalid key form.",
184
+ -10003 => "Can't set reference to given value. Access not allowed.",
185
+ -10004 => "A privilege violation occurred.",
186
+ -10005 => "The read operation wasn't allowed.",
187
+ -10006 => "Can't set reference to given value.",
188
+ -10007 => "The index of the event is too large to be valid.",
189
+ -10008 => "The specified object is a property, not an element.",
190
+ -10009 => "Can't supply the requested descriptor type for the data.",
191
+ -10010 => "The Apple event handler can't handle objects of this class.",
192
+ -10011 => "Couldn't handle this command because it wasn't part of the current transaction.",
193
+ -10012 => "The transaction to which this command belonged isn't a valid transaction.",
194
+ -10013 => "There is no user selection.",
195
+ -10014 => "Handler only handles single objects.",
196
+ -10015 => "Can't undo the previous Apple event or user action.",
197
+ -10023 => "Enumerated value is not allowed for this property.",
198
+ -10024 => "Class can't be an element of container.",
199
+ -10025 => "Illegal combination of properties settings.",
200
+ }
201
+
202
+ # Following Cocoa Scripting error descriptions taken from:
203
+ # http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSScriptCommand.html
204
+ # http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSScriptObjectSpecifier.html
205
+
206
+ CocoaErrorDescriptions = [
207
+ ["NSReceiverEvaluationScriptError", "The object or objects specified by the direct parameter to a command could not be found."],
208
+ ["NSKeySpecifierEvaluationScriptError", "The object or objects specified by a key (for commands that support key specifiers) could not be found."],
209
+ ["NSArgumentEvaluationScriptError", "The object specified by an argument could not be found."],
210
+ ["NSReceiversCantHandleCommandScriptError", "The receivers don't support the command sent to them."],
211
+ ["NSRequiredArgumentsMissingScriptError", "An argument (or more than one argument) is missing."],
212
+ ["NSArgumentsWrongScriptError", "An argument (or more than one argument) is of the wrong type or is otherwise invalid."],
213
+ ["NSUnknownKeyScriptError", "An unidentified error occurred; indicates an error in the scripting support of the application."],
214
+ ["NSInternalScriptError", "An unidentified internal error occurred; indicates an error in the scripting support of the application."],
215
+ ["NSOperationNotSupportedForKeyScriptError", "The implementation of a scripting command signaled an error."],
216
+ ["NSCannotCreateScriptCommandError", "Could not create the script command; an invalid or unrecognized Apple event was received."],
217
+ ["NSNoSpecifierError", "No error encountered."],
218
+ ["NSNoTopLevelContainersSpecifierError", "Someone called evaluate with nil."],
219
+ ["NSContainerSpecifierError", "Error evaluating container specifier."],
220
+ ["NSUnknownKeySpecifierError", "Receivers do not understand the key."],
221
+ ["NSInvalidIndexSpecifierError", "Index out of bounds."],
222
+ ["NSInternalSpecifierError", "Other internal error."],
223
+ ["NSOperationNotSupportedForKeySpecifierError", "Attempt made to perform an unsupported operation on some key."]
224
+ ]
225
+
226
+ attr_reader :number, :raw
227
+ alias_method :to_i, :number
228
+
229
+ def initialize(number, reply_params={})
230
+ @number = number
231
+ @message = nil
232
+ @raw = reply_params
233
+ end
234
+
235
+ def message
236
+ if not @message
237
+ desc = @raw[KAE::KeyErrorString]
238
+ @message = DefaultCodecs.unpack(desc) if desc
239
+ if @message.is_a?(String) and @number > 0
240
+ # add clarification to default Cocoa Scripting error messages
241
+ CocoaErrorDescriptions.each do |name, description|
242
+ if @message[0, name.length] == name
243
+ @message += " (#{description})"
244
+ break
245
+ end
246
+ end
247
+ end
248
+ # if no message supplied or is a MacOSError, use default message if one is available
249
+ @message = MacOSErrorDescriptions.fetch(number, '') if @message == nil
250
+ end
251
+ return @message
252
+ end
253
+
254
+ def to_s
255
+ if message != ''
256
+ return "EventError\n\t\tOSERROR: #{number}\n\t\tMESSAGE: #{message}"
257
+ else
258
+ return "EventError\n\t\tOSERROR: #{number}"
259
+ end
260
+ end
261
+
262
+ # extended error info (some apps may return additional error info, though most don't)
263
+
264
+ def offending_object
265
+ desc = @raw[KAE::KOSAErrorOffendingObject]
266
+ return desc ? DefaultCodecs.unpack(desc) : nil
267
+ end
268
+
269
+ def expected_type
270
+ desc = @raw[KAE::KOSAErrorExpectedType]
271
+ return desc ? DefaultCodecs.unpack(desc) : nil
272
+ end
273
+
274
+ def partial_result
275
+ desc = @raw[KAE::KOSAErrorPartialResult]
276
+ return desc ? DefaultCodecs.unpack(desc) : nil
277
+ end
278
+ end
279
279
  end