Class: Osaka::RemoteControl

Inherits:
Object
  • Object
show all
Defined in:
lib/osaka/remotecontrol.rb

Constant Summary collapse

@@debug_info_enabled =
false

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, base_location = Location.new("")) ⇒ RemoteControl

Returns a new instance of RemoteControl.



24
25
26
27
# File 'lib/osaka/remotecontrol.rb', line 24

def initialize(name, base_location = Location.new(""))
  @name = name
  @base_location = base_location
end

Instance Attribute Details

#base_locationObject

Returns the value of attribute base_location.



12
13
14
# File 'lib/osaka/remotecontrol.rb', line 12

def base_location
  @base_location
end

#nameObject (readonly)

Returns the value of attribute name.



11
12
13
# File 'lib/osaka/remotecontrol.rb', line 11

def name
  @name
end

Class Method Details

.enable_debug_printsObject



16
17
18
# File 'lib/osaka/remotecontrol.rb', line 16

def self.enable_debug_prints
  @@debug_info_enabled = true
end

Instance Method Details

#==(obj) ⇒ Object



29
30
31
# File 'lib/osaka/remotecontrol.rb', line 29

def ==(obj)
  @name == obj.name && base_location == obj.base_location
end

#activateObject



54
55
56
# File 'lib/osaka/remotecontrol.rb', line 54

def activate
  check_output( tell("activate"), "activate" )
end

#attributes(location = "") ⇒ Object



206
207
208
209
210
211
# File 'lib/osaka/remotecontrol.rb', line 206

def attributes(location = "")
  attributelist = get!("attributes", location)
  attributelist.split("of application process #{name}").collect { |attribute|
    attribute.match("attribute (.+?) .*")[1]
  }
end

#check_output(output, action) ⇒ Object



49
50
51
52
# File 'lib/osaka/remotecontrol.rb', line 49

def check_output(output, action)
  print_warning(action, output) unless output.empty?
  output
end

#click(element) ⇒ Object



153
154
155
156
# File 'lib/osaka/remotecontrol.rb', line 153

def click(element)
  activate
  click!(element)
end

#click!(element) ⇒ Object



147
148
149
150
151
# File 'lib/osaka/remotecontrol.rb', line 147

def click!(element)
  # Click seems to often output stuff, but it doesn't have much meaning so we ignore it.
  system_event!("click #{construct_location(element)}")
  self
end

#click_menu_bar(menu_item, menu_name) ⇒ Object



158
159
160
161
162
# File 'lib/osaka/remotecontrol.rb', line 158

def click_menu_bar(menu_item, menu_name)
  activate
  menu_bar_location = at.menu_bar_item(menu_name).menu_bar(1)
  click!(menu_item + at.menu(1) + menu_bar_location)
end

#construct_key_statement(key_keys) ⇒ Object



131
132
133
134
# File 'lib/osaka/remotecontrol.rb', line 131

def construct_key_statement(key_keys)
  return "return" if key_keys == :return
  "\"#{key_keys}\""
end

#construct_location(location) ⇒ Object



189
190
191
# File 'lib/osaka/remotecontrol.rb', line 189

def construct_location(location)
  form_location_with_window(location).to_s
end

#construct_modifier_statement(modifier_keys) ⇒ Object



125
126
127
128
129
# File 'lib/osaka/remotecontrol.rb', line 125

def construct_modifier_statement(modifier_keys)
  modified_key_string = [ modifier_keys ].flatten.collect! { |mod_key| mod_key.to_s + " down"}.join(", ")
  modifier_command = " using {#{modified_key_string}}" unless modifier_keys.empty?
  modifier_command
end

#construct_prefixed_location(location) ⇒ Object



193
194
195
# File 'lib/osaka/remotecontrol.rb', line 193

def construct_prefixed_location(location)
  form_location_with_window(location).as_prefixed_location
end

#convert_mac_version_string_to_symbol(version_string) ⇒ Object



271
272
273
# File 'lib/osaka/remotecontrol.rb', line 271

def convert_mac_version_string_to_symbol(version_string)

end

#current_window_invalid?(window_list) ⇒ Boolean

Returns:

  • (Boolean)


244
245
246
# File 'lib/osaka/remotecontrol.rb', line 244

def current_window_invalid?(window_list)
  @base_location.to_s.empty? || window_list.index(current_window_name).nil?
end

#current_window_nameObject



238
239
240
241
242
# File 'lib/osaka/remotecontrol.rb', line 238

def current_window_name
  matchdata = @base_location.to_s.match(/window "(.*)"/)
  return "" if matchdata.nil? || matchdata[1].nil?
  matchdata[1]
end

#debug_print(message) ⇒ Object



20
21
22
# File 'lib/osaka/remotecontrol.rb', line 20

def debug_print(message)
  puts message if @@debug_info_enabled
end

#exists?(location) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/osaka/remotecontrol.rb', line 71

def exists?(location)
  system_event!("exists #{construct_location(location)}").strip == "true"
end

#focusObject



169
170
171
172
173
174
175
176
177
# File 'lib/osaka/remotecontrol.rb', line 169

def focus
  if (base_location.to_s.empty? || not_exists?(base_location))
    currently_active_window = window_list[0]
    currently_active_window ||= ""
    @base_location = (currently_active_window.to_s.empty?) ? Location.new("") : at.window(currently_active_window)
  end

  focus!
end

#focus!Object



179
180
181
# File 'lib/osaka/remotecontrol.rb', line 179

def focus!
  system_event!("set value of attribute \"AXMain\" of #{base_location.top_level_element} to true") unless base_location.top_level_element.to_s.empty?
end

#form_location_with_window(location) ⇒ Object



183
184
185
186
187
# File 'lib/osaka/remotecontrol.rb', line 183

def form_location_with_window(location)
  new_location = Location.new(location)
  new_location += @base_location unless new_location.has_top_level_element?
  new_location
end

#get!(element, location = "") ⇒ Object



197
198
199
200
# File 'lib/osaka/remotecontrol.rb', line 197

def get!(element, location = "")
  debug_print "Getting attribute '#{element}' of: #{construct_prefixed_location(location)}"
  system_event!("get #{element}#{construct_prefixed_location(location)}").strip
end

#get_app!(element) ⇒ Object



202
203
204
# File 'lib/osaka/remotecontrol.rb', line 202

def get_app!(element)
  system_event!("get #{element}").strip
end

#keystroke(key, modifier_keys = []) ⇒ Object



141
142
143
144
145
# File 'lib/osaka/remotecontrol.rb', line 141

def keystroke(key, modifier_keys = [])
  activate
  focus
  (modifier_keys == []) ? keystroke!(key) : keystroke!(key, modifier_keys)
end

#keystroke!(key, modifier_keys = []) ⇒ Object



136
137
138
139
# File 'lib/osaka/remotecontrol.rb', line 136

def keystroke!(key, modifier_keys = [])
  check_output( system_event!("keystroke #{construct_key_statement(key)}#{construct_modifier_statement(modifier_keys)}"), "keystroke")
  self
end

#launchObject



58
59
60
# File 'lib/osaka/remotecontrol.rb', line 58

def launch
  check_output( tell("launch"), "launch" )
end

#mac_versionObject



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/osaka/remotecontrol.rb', line 248

def mac_version
  @mac_version_string ||= Osaka::ScriptRunner.execute("system version of (system info)").strip
  @mac_version ||= case @mac_version_string
    when /^10.6.*/
      :snow_leopard
    when /^10.7.*/
      :lion
    when /^10.8.*/
      :mountain_lion
    when /^10.10.*/
      :yosemite
    else
      :other
    end

end

#mac_version_stringObject



265
266
267
268
# File 'lib/osaka/remotecontrol.rb', line 265

def mac_version_string
  mac_version
  @mac_version_string
end

#not_exists?(location) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/osaka/remotecontrol.rb', line 75

def not_exists?(location)
  system_event!("not exists #{construct_location(location)}").strip == "true"
end


45
46
47
# File 'lib/osaka/remotecontrol.rb', line 45

def print_warning(action, message)
  puts "Osaka WARNING while doing #{action}: #{message}"
end

#quitObject



62
63
64
# File 'lib/osaka/remotecontrol.rb', line 62

def quit
  keystroke("q", :command)
end

#running?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/osaka/remotecontrol.rb', line 41

def running?
  ScriptRunner::execute("tell application \"System Events\"; (name of processes) contains \"#{@name}\"; end tell").strip == "true"
end

#set(element, location, value) ⇒ Object



213
214
215
216
# File 'lib/osaka/remotecontrol.rb', line 213

def set(element, location, value)
  activate
  set!(element, location, value)
end

#set!(element, location, value) ⇒ Object



164
165
166
167
# File 'lib/osaka/remotecontrol.rb', line 164

def set!(element, location, value)
  encoded_value = (value.class == String) ? "\"#{value}\"" : value.to_s
  check_output( system_event!("set #{element}#{construct_prefixed_location(location)} to #{encoded_value}"), "set")
end

#set_current_window(window_name) ⇒ Object



233
234
235
236
# File 'lib/osaka/remotecontrol.rb', line 233

def set_current_window(window_name)
  debug_print "Changing remote base location to: #{window_name}"
  @base_location = at.window(window_name)
end

#standard_window_listObject



225
226
227
228
229
230
231
# File 'lib/osaka/remotecontrol.rb', line 225

def standard_window_list
  window_list.collect { |window|
    if exists?(at.window(window)) && get!("subrole", at.window(window)) == "AXStandardWindow"
      window
    end
  }.compact
end

#system_event(event) ⇒ Object



66
67
68
69
# File 'lib/osaka/remotecontrol.rb', line 66

def system_event(event)
  activate
  system_event!(event)
end

#system_event!(event) ⇒ Object



37
38
39
# File 'lib/osaka/remotecontrol.rb', line 37

def system_event!(event)
  ScriptRunner::execute("tell application \"System Events\"; tell process \"#{@name}\"; #{event}; end tell; end tell")
end

#tell(command) ⇒ Object



33
34
35
# File 'lib/osaka/remotecontrol.rb', line 33

def tell(command)
  ScriptRunner::execute("tell application \"#{@name}\"; #{command}; end tell")
end

#wait_until(locations, action) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/osaka/remotecontrol.rb', line 79

def wait_until(locations, action)

  begin
    Timeout::timeout(10) {
      while(true)
          locations.flatten.each { |location|
            return location if yield location
        }
        action.() unless action.nil?
      end
    }
  rescue Exception
    raise Osaka::TimeoutError, "Timed out while waiting for: #{locations.join(", ")}"
  end
end

#wait_until_exists(*locations, &action) ⇒ Object Also known as: until_exists



95
96
97
98
# File 'lib/osaka/remotecontrol.rb', line 95

def wait_until_exists(*locations, &action)
  activate
  wait_until_exists!(*locations, &action)
end

#wait_until_exists!(*locations, &action) ⇒ Object Also known as: until_exists!



100
101
102
103
104
105
# File 'lib/osaka/remotecontrol.rb', line 100

def wait_until_exists!(*locations, &action)
  wait_until(locations, action) { |location|
    debug_print "Waiting until exists: #{location.to_s} on remote #{current_window_name.to_s}"
    exists?(location)
  }
end

#wait_until_not_exists(*locations, &action) ⇒ Object Also known as: until_not_exists



110
111
112
113
# File 'lib/osaka/remotecontrol.rb', line 110

def wait_until_not_exists(*locations, &action)
  activate
  wait_until_not_exists!(*locations, &action)
end

#wait_until_not_exists!(*locations, &action) ⇒ Object Also known as: until_not_exists!



115
116
117
118
119
# File 'lib/osaka/remotecontrol.rb', line 115

def wait_until_not_exists!(*locations, &action)
  wait_until(locations, action) { |location|
    not_exists?(location)
  }
end

#window_listObject



218
219
220
221
222
223
# File 'lib/osaka/remotecontrol.rb', line 218

def window_list
  windows = get_app!("windows").strip.split(',')
  windows.collect { |window|
    window[7...window =~ / of application process/].strip
  }
end