Package lib ::
Module scripting
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import subprocess, threading, time, re
20
21
22
23
24
25
26
27
29 """
30 Provides access to the keyboard for event generation.
31 """
32
34 self.mediator = mediator
35
37 """
38 Send a sequence of keys via keyboard events
39
40 Usage: C{keyboard.send_keys(keyString)}
41
42 @param keyString: string of keys (including special keys) to send
43 """
44 self.mediator.interface.begin_send()
45 self.mediator.send_string(keyString.decode("utf-8"))
46 self.mediator.interface.finish_send()
47
49 """
50 Send a keyboard event
51
52 Usage: C{keyboard.send_key(key, repeat=1)}
53
54 @param key: they key to be sent (e.g. "s" or "<enter>")
55 @param repeat: number of times to repeat the key event
56 """
57 for x in xrange(repeat):
58 self.mediator.send_key(key.decode("utf-8"))
59 self.mediator.flush()
60
62 """
63 Send a key down event
64
65 Usage: C{keyboard.press_key(key)}
66
67 The key will be treated as down until a matching release_key() is sent.
68 @param key: they key to be pressed (e.g. "s" or "<enter>")
69 """
70 self.mediator.press_key(key.decode("utf-8"))
71
73 """
74 Send a key up event
75
76 Usage: C{keyboard.release_key(key)}
77
78 If the specified key was not made down using press_key(), the event will be
79 ignored.
80 @param key: they key to be released (e.g. "s" or "<enter>")
81 """
82 self.mediator.release_key(key.decode("utf-8"))
83
85 """
86 Fake a keypress
87
88 Usage: C{keyboard.fake_keypress(key, repeat=1)}
89
90 Uses XTest to 'fake' a keypress. This is useful to send keypresses to some
91 applications which won't respond to keyboard.send_key()
92
93 @param key: they key to be sent (e.g. "s" or "<enter>")
94 @param repeat: number of times to repeat the key event
95 """
96 for x in xrange(repeat):
97 self.mediator.fake_keypress(key.decode("utf-8"))
98
99
100
102 """
103 Provides access to send mouse clicks
104 """
106 self.mediator = mediator
107
109 """
110 Send a mouse click relative to the active window
111
112 Usage: C{mouse.click_relative(x, y, button)}
113
114 @param x: x-coordinate in pixels, relative to upper left corner of window
115 @param y: y-coordinate in pixels, relative to upper left corner of window
116 @param button: mouse button to simulate (left=1, middle=2, right=3)
117 """
118 self.mediator.send_mouse_click(x, y, button, True)
119
121 """
122 Send a mouse click relative to the screen (absolute)
123
124 Usage: C{mouse.click_absolute(x, y, button)}
125
126 @param x: x-coordinate in pixels, relative to upper left corner of window
127 @param y: y-coordinate in pixels, relative to upper left corner of window
128 @param button: mouse button to simulate (left=1, middle=2, right=3)
129 """
130 self.mediator.send_mouse_click(x, y, button, False)
131
132
134 """
135 Allows persistent storage of values between invocations of the script.
136 """
137
139 """
140 Store a value
141
142 Usage: C{store.set_value(key, value)}
143 """
144 self[key] = value
145
147 """
148 Get a value
149
150 Usage: C{store.get_value(key)}
151 """
152 return self[key]
153
155 """
156 Remove a value
157
158 Usage: C{store.remove_value(key)}
159 """
160 del self[key]
161
163 """
164 Provides a simple interface for the display of some basic dialogs to collect information from the user.
165
166 This version uses KDialog to integrate well with KDE.
167
168 A note on exit codes: an exit code of 0 indicates that the user clicked OK.
169 """
170
172 p = subprocess.Popen(["kdialog", "--title", title] + args, stdout=subprocess.PIPE)
173 retCode = p.wait()
174 output = p.stdout.read()[:-1]
175
176 return (retCode, output)
177
191
192 - def password_dialog(self, title="Enter password", message="Enter password"):
193 """
194 Show a password input dialog
195
196 Usage: C{dialog.password_dialog(title="Enter password", message="Enter password")}
197
198 @param title: window title for the dialog
199 @param message: message displayed above the password input box
200 @return: a tuple containing the exit code and user input
201 @rtype: C{tuple(int, str)}
202 """
203 return self.__runKdialog(title, ["--password", message])
204
206 """
207 Show a combobox menu
208
209 Usage: C{dialog.combo_menu(options, title="Choose an option", message="Choose an option")}
210
211 @param options: list of options (strings) for the dialog
212 @param title: window title for the dialog
213 @param message: message displayed above the combobox
214 @return: a tuple containing the exit code and user choice
215 @rtype: C{tuple(int, str)}
216 """
217 return self.__runKdialog(title, ["--combobox", message] + options)
218
220 """
221 Show a single-selection list menu
222
223 Usage: C{dialog.list_menu(options, title="Choose a value", message="Choose a value", default=None)}
224
225 @param options: list of options (strings) for the dialog
226 @param title: window title for the dialog
227 @param message: message displayed above the list
228 @param default: default value to be selected
229 @return: a tuple containing the exit code and user choice
230 @rtype: C{tuple(int, str)}
231 """
232
233 choices = []
234 optionNum = 0
235 for option in options:
236 choices.append(str(optionNum))
237 choices.append(option)
238 if option == default:
239 choices.append("on")
240 else:
241 choices.append("off")
242 optionNum += 1
243
244 retCode, result = self.__runKdialog(title, ["--radiolist", message] + choices)
245 choice = options[int(result)]
246
247 return retCode, choice
248
250 """
251 Show a multiple-selection list menu
252
253 Usage: C{dialog.list_menu_multi(options, title="Choose one or more values", message="Choose one or more values", defaults=[])}
254
255 @param options: list of options (strings) for the dialog
256 @param title: window title for the dialog
257 @param message: message displayed above the list
258 @param defaults: list of default values to be selected
259 @return: a tuple containing the exit code and user choice
260 @rtype: C{tuple(int, str)}
261 """
262
263 choices = []
264 optionNum = 0
265 for option in options:
266 choices.append(str(optionNum))
267 choices.append(option)
268 if option in defaults:
269 choices.append("on")
270 else:
271 choices.append("off")
272 optionNum += 1
273
274 retCode, output = self.__runKdialog(title, ["--separate-output", "--checklist", message] + choices)
275 results = output.split()
276
277 choices = []
278 for index in results:
279 choices.append(options[int(index)])
280
281 return retCode, choices
282
283 - def open_file(self, title="Open File", initialDir="~", fileTypes="*|All Files", rememberAs=None):
284 """
285 Show an Open File dialog
286
287 Usage: C{dialog.open_file(title="Open File", initialDir="~", fileTypes="*|All Files", rememberAs=None)}
288
289 @param title: window title for the dialog
290 @param initialDir: starting directory for the file dialog
291 @param fileTypes: file type filter expression
292 @param rememberAs: gives an ID to this file dialog, allowing it to open at the last used path next time
293 @return: a tuple containing the exit code and file path
294 @rtype: C{tuple(int, str)}
295 """
296 if rememberAs is not None:
297 return self.__runKdialog(title, ["--getopenfilename", initialDir, fileTypes, ":" + rememberAs])
298 else:
299 return self.__runKdialog(title, ["--getopenfilename", initialDir, fileTypes])
300
301 - def save_file(self, title="Save As", initialDir="~", fileTypes="*|All Files", rememberAs=None):
302 """
303 Show a Save As dialog
304
305 Usage: C{dialog.save_file(title="Save As", initialDir="~", fileTypes="*|All Files", rememberAs=None)}
306
307 @param title: window title for the dialog
308 @param initialDir: starting directory for the file dialog
309 @param fileTypes: file type filter expression
310 @param rememberAs: gives an ID to this file dialog, allowing it to open at the last used path next time
311 @return: a tuple containing the exit code and file path
312 @rtype: C{tuple(int, str)}
313 """
314 if rememberAs is not None:
315 return self.__runKdialog(title, ["--getsavefilename", initialDir, fileTypes, ":" + rememberAs])
316 else:
317 return self.__runKdialog(title, ["--getsavefilename", initialDir, fileTypes])
318
319 - def choose_directory(self, title="Select Directory", initialDir="~", rememberAs=None):
320 """
321 Show a Directory Chooser dialog
322
323 Usage: C{dialog.choose_directory(title="Select Directory", initialDir="~", rememberAs=None)}
324
325 @param title: window title for the dialog
326 @param initialDir: starting directory for the directory chooser dialog
327 @param rememberAs: gives an ID to this file dialog, allowing it to open at the last used path next time
328 @return: a tuple containing the exit code and chosen path
329 @rtype: C{tuple(int, str)}
330 """
331 if rememberAs is not None:
332 return self.__runKdialog(title, ["--getexistingdirectory", initialDir, ":" + rememberAs])
333 else:
334 return self.__runKdialog(title, ["--getexistingdirectory", initialDir])
335
337 """
338 Show a Colour Chooser dialog
339
340 Usage: C{dialog.choose_colour(title="Select Colour")}
341
342 @param title: window title for the dialog
343 @return: a tuple containing the exit code and colour
344 @rtype: C{tuple(int, str)}
345 """
346 return self.__runKdialog(title, ["--getcolor"])
347
348
350 """
351 Simplified access to some system commands.
352 """
353
355 """
356 Execute a shell command
357
358 Set getOutput to False if the command does not exit and return immediately. Otherwise
359 AutoKey will not respond to any hotkeys/abbreviations etc until the process started
360 by the command exits.
361
362 Usage: C{system.exec_command(command, getOutput=True)}
363
364 @param command: command to be executed (including any arguments) - e.g. "ls -l"
365 @param getOutput: whether to capture the (stdout) output of the command
366 @raise subprocess.CalledProcessError: if the command returns a non-zero exit code
367 """
368 if getOutput:
369 p = subprocess.Popen(command, shell=True, bufsize=-1, stdout=subprocess.PIPE)
370 retCode = p.wait()
371 output = p.stdout.read()[:-1]
372 if retCode != 0:
373 raise subprocess.CalledProcessError(retCode, output)
374 else:
375 return output
376 else:
377 subprocess.Popen(command, shell=True, bufsize=-1)
378
380 """
381 Create a file with contents
382
383 Usage: C{system.create_file(fileName, contents="")}
384
385 @param fileName: full path to the file to be created
386 @param contents: contents to insert into the file
387 """
388 f = open(fileName, "w")
389 f.write(contents)
390 f.close()
391
392
394 """
395 Provides a simple interface for the display of some basic dialogs to collect information from the user.
396
397 This version uses Zenity to integrate well with GNOME.
398
399 A note on exit codes: an exit code of 0 indicates that the user clicked OK.
400 """
401
403 p = subprocess.Popen(["zenity", "--title", title] + args, stdout=subprocess.PIPE)
404 retCode = p.wait()
405 output = p.stdout.read()[:-1]
406
407 return (retCode, output)
408
422
423 - def password_dialog(self, title="Enter password", message="Enter password"):
424 """
425 Show a password input dialog
426
427 Usage: C{dialog.password_dialog(title="Enter password", message="Enter password")}
428
429 @param title: window title for the dialog
430 @param message: message displayed above the password input box
431 @return: a tuple containing the exit code and user input
432 @rtype: C{tuple(int, str)}
433 """
434 return self.__runZenity(title, ["--entry", "--text", message, "--hide-text"])
435
436
437 """
438 Show a combobox menu - not supported by zenity
439
440 Usage: C{dialog.combo_menu(options, title="Choose an option", message="Choose an option")}
441
442 @param options: list of options (strings) for the dialog
443 @param title: window title for the dialog
444 @param message: message displayed above the combobox
445 """
446
447
449 """
450 Show a single-selection list menu
451
452 Usage: C{dialog.list_menu(options, title="Choose a value", message="Choose a value", default=None)}
453
454 @param options: list of options (strings) for the dialog
455 @param title: window title for the dialog
456 @param message: message displayed above the list
457 @param default: default value to be selected
458 @return: a tuple containing the exit code and user choice
459 @rtype: C{tuple(int, str)}
460 """
461
462 choices = []
463
464 for option in options:
465 if option == default:
466 choices.append("TRUE")
467 else:
468 choices.append("FALSE")
469
470
471 choices.append(option)
472
473
474 return self.__runZenity(title, ["--list", "--radiolist", "--text", message, "--column", " ", "--column", "Options"] + choices)
475
476
477
479 """
480 Show a multiple-selection list menu
481
482 Usage: C{dialog.list_menu_multi(options, title="Choose one or more values", message="Choose one or more values", defaults=[])}
483
484 @param options: list of options (strings) for the dialog
485 @param title: window title for the dialog
486 @param message: message displayed above the list
487 @param defaults: list of default values to be selected
488 @return: a tuple containing the exit code and user choice
489 @rtype: C{tuple(int, str)}
490 """
491
492 choices = []
493
494 for option in options:
495 if option in defaults:
496 choices.append("TRUE")
497 else:
498 choices.append("FALSE")
499
500
501 choices.append(option)
502
503
504 retCode, output = self.__runZenity(title, ["--list", "--checklist", "--text", message, "--column", " ", "--column", "Options"] + choices)
505 results = output.split('|')
506
507
508
509
510
511 return retCode, results
512
514 """
515 Show an Open File dialog
516
517 Usage: C{dialog.open_file(title="Open File")}
518
519 @param title: window title for the dialog
520 @return: a tuple containing the exit code and file path
521 @rtype: C{tuple(int, str)}
522 """
523
524
525
526 return self.__runZenity(title, ["--file-selection"])
527
529 """
530 Show a Save As dialog
531
532 Usage: C{dialog.save_file(title="Save As")}
533
534 @param title: window title for the dialog
535 @return: a tuple containing the exit code and file path
536 @rtype: C{tuple(int, str)}
537 """
538
539
540
541 return self.__runZenity(title, ["--file-selection", "--save"])
542
544 """
545 Show a Directory Chooser dialog
546
547 Usage: C{dialog.choose_directory(title="Select Directory")}
548
549 @param title: window title for the dialog
550 @return: a tuple containing the exit code and path
551 @rtype: C{tuple(int, str)}
552 """
553
554
555
556 return self.__runZenity(title, ["--file-selection", "--directory"])
557
558
559 """
560 Show a Colour Chooser dialog - not supported by zenity
561
562 Usage: C{dialog.choose_colour(title="Select Colour")}
563
564 @param title: window title for the dialog
565 """
566
567
568 - def calendar(self, title="Choose a date", format="%Y-%m-%d", date="today"):
569 """
570 Show a calendar dialog
571
572 Usage: C{dialog.calendar_dialog(title="Choose a date", format="%Y-%m-%d", date="YYYY-MM-DD")}
573
574 @param title: window title for the dialog
575 @param format: format of date to be returned
576 @param date: initial date as YYYY-MM-DD, otherwise today
577 @return: a tuple containing the exit code and date
578 @rtype: C{tuple(int, str)}
579 """
580 if re.match(r"[0-9]{4}-[0-9]{2}-[0-9]{2}", date):
581 year = date[0:4]
582 month = date[5:7]
583 day = date[8:10]
584 date_args = ["--year=" + year, "--month=" + month, "--day=" + day]
585 else:
586 date_args = []
587 return self.__runZenity(title, ["--calendar", "--date-format=" + format] + date_args)
588
589
591 """
592 Read/write access to the X selection and clipboard - QT version
593 """
594
596 self.clipBoard = QApplication.clipboard()
597 self.app = app
598
600 """
601 Copy text into the X selection
602
603 Usage: C{clipboard.fill_selection(contents)}
604
605 @param contents: string to be placed in the selection
606 """
607 self.__execAsync(self.__fillSelection, contents)
608
610 self.clipBoard.setText(string, QClipboard.Selection)
611 self.sem.release()
612
614 """
615 Read text from the X selection
616
617 Usage: C{clipboard.get_selection()}
618
619 @return: text contents of the mouse selection
620 @rtype: C{str}
621 """
622 self.__execAsync(self.__getSelection)
623 return str(self.text)
624
626 self.text = self.clipBoard.text(QClipboard.Selection)
627 self.sem.release()
628
630 """
631 Copy text into the clipboard
632
633 Usage: C{clipboard.fill_clipboard(contents)}
634
635 @param contents: string to be placed in the selection
636 """
637 self.__execAsync(self.__fillClipboard, contents)
638
640 self.clipBoard.setText(string, QClipboard.Clipboard)
641 self.sem.release()
642
644 """
645 Read text from the clipboard
646
647 Usage: C{clipboard.get_clipboard()}
648
649 @return: text contents of the clipboard
650 @rtype: C{str}
651 """
652 self.__execAsync(self.__getClipboard)
653 return str(self.text)
654
656 self.text = self.clipBoard.text(QClipboard.Clipboard)
657 self.sem.release()
658
660 self.sem = threading.Semaphore(0)
661 self.app.exec_in_main(callback, *args)
662 self.sem.acquire()
663
664
666 """
667 Read/write access to the X selection and clipboard - GTK version
668 """
669
671 self.clipBoard = gtk.Clipboard()
672 self.selection = gtk.Clipboard(selection="PRIMARY")
673 self.app = app
674
676 """
677 Copy text into the X selection
678
679 Usage: C{clipboard.fill_selection(contents)}
680
681 @param contents: string to be placed in the selection
682 """
683
684 self.__fillSelection(contents)
685
687 gtk.gdk.threads_enter()
688 self.selection.set_text(string.encode("utf-8"))
689 gtk.gdk.threads_leave()
690
691
693 """
694 Read text from the X selection
695
696 Usage: C{clipboard.get_selection()}
697
698 @return: text contents of the mouse selection
699 @rtype: C{str}
700 @raise Exception: if no text was found in the selection
701 """
702 self.__execAsync(self.selection.request_text, self.__receive)
703 if self.text is not None:
704 return self.text.decode("utf-8")
705 else:
706 raise Exception("No text found in X selection")
707
709 self.text = text
710 self.sem.release()
711
713 """
714 Copy text into the clipboard
715
716 Usage: C{clipboard.fill_clipboard(contents)}
717
718 @param contents: string to be placed in the selection
719 """
720 self.__fillClipboard(contents)
721
723 gtk.gdk.threads_enter()
724 self.clipBoard.set_text(string.encode("utf-8"))
725 gtk.gdk.threads_leave()
726
727
729 """
730 Read text from the clipboard
731
732 Usage: C{clipboard.get_clipboard()}
733
734 @return: text contents of the clipboard
735 @rtype: C{str}
736 @raise Exception: if no text was found on the clipboard
737 """
738 self.__execAsync(self.clipBoard.request_text, self.__receive)
739 if self.text is not None:
740 return self.text.decode("utf-8")
741 else:
742 raise Exception("No text found on clipboard")
743
745 self.sem = threading.Semaphore(0)
746 gtk.gdk.threads_enter()
747 callback(*args)
748 gtk.gdk.threads_leave()
749 self.sem.acquire()
750
751
753 """
754 Basic window management using wmctrl
755
756 Note: in all cases where a window title is required (with the exception of wait_for_focus()),
757 two special values of window title are permitted:
758
759 :ACTIVE: - select the currently active window
760 :SELECT: - select the desired window by clicking on it
761 """
762
764 self.mediator = mediator
765
767 """
768 Wait for window with the given title to have focus
769
770 Usage: C{window.wait_for_focus(title, timeOut=5)}
771
772 If the window becomes active, returns True. Otherwise, returns False if
773 the window has not become active by the time the timeout has elapsed.
774
775 @param title: title to match against (as a regular expression)
776 @param timeOut: period (seconds) to wait before giving up
777 @rtype: boolean
778 """
779 regex = re.compile(title)
780 waited = 0
781 while waited < timeOut:
782 if regex.match(self.mediator.interface.get_window_title()):
783 return True
784 time.sleep(0.3)
785 waited += 0.3
786
787 return False
788
790 """
791 Wait for window with the given title to be created
792
793 Usage: C{window.wait_for_exist(title, timeOut=5)}
794
795 If the window is in existence, returns True. Otherwise, returns False if
796 the window has not been created by the time the timeout has elapsed.
797
798 @param title: title to match against (as a regular expression)
799 @param timeOut: period (seconds) to wait before giving up
800 @rtype: boolean
801 """
802 regex = re.compile(title)
803 waited = 0
804 while waited < timeOut:
805 retCode, output = self.__runWmctrl(["-l"])
806 for line in output.split('\n'):
807 if regex.match(line[14:].split(' ', 1)[-1]):
808 return True
809
810 time.sleep(0.3)
811 waited += 0.3
812
813 return False
814
815 - def activate(self, title, switchDesktop=False):
816 """
817 Activate the specified window, giving it input focus
818
819 Usage: C{window.activate(title, switchDesktop=False)}
820
821 If switchDesktop is False (default), the window will be moved to the current desktop
822 and activated. Otherwise, switch to the window's current desktop and activate it there.
823
824 @param title: window title to match against (as case-insensitive substring match)
825 @param switchDesktop: whether or not to switch to the window's current desktop
826 """
827 if switchDesktop:
828 args = ["-a", title]
829 else:
830 args = ["-R", title]
831 self.__runWmctrl(args)
832
834 """
835 Close the specified window gracefully
836
837 Usage: C{window.close(title)}
838
839 @param title: window title to match against (as case-insensitive substring match)
840 """
841 self.__runWmctrl(["-c", title])
842
843 - def resize_move(self, title, xOrigin=-1, yOrigin=-1, width=-1, height=-1):
844 """
845 Resize and/or move the specified window
846
847 Usage: C{window.close(title, xOrigin=-1, yOrigin=-1, width=-1, height=-1)}
848
849 Leaving and of the position/dimension values as the default (-1) will cause that
850 value to be left unmodified.
851
852 @param title: window title to match against (as case-insensitive substring match)
853 @param xOrigin: new x origin of the window (upper left corner)
854 @param yOrigin: new y origin of the window (upper left corner)
855 @param width: new width of the window
856 @param height: new height of the window
857 """
858 mvArgs = ["0", str(xOrigin), str(yOrigin), str(width), str(height)]
859 self.__runWmctrl(["-r", title, "-e", ','.join(mvArgs)])
860
861
863 """
864 Move the specified window to the given desktop
865
866 Usage: C{window.move_to_desktop(title, deskNum)}
867
868 @param title: window title to match against (as case-insensitive substring match)
869 @param deskNum: desktop to move the window to (note: zero based)
870 """
871 self.__runWmctrl(["-r", title, "-t", str(deskNum)])
872
873
875 """
876 Switch to the specified desktop
877
878 Usage: C{window.switch_desktop(deskNum)}
879
880 @param deskNum: desktop to switch to (note: zero based)
881 """
882 self.__runWmctrl(["-s", str(deskNum)])
883
885 """
886 Set a property on the given window using the specified action
887
888 Usage: C{window.set_property(title, title, action, prop)}
889
890 Allowable actions: C{add, remove, toggle}
891 Allowable properties: C{modal, sticky, maximized_vert, maximized_horz, shaded, skip_taskbar,
892 skip_pager, hidden, fullscreen, above}
893
894 @param title: window title to match against (as case-insensitive substring match)
895 @param action: one of the actions listed above
896 @param prop: one of the properties listed above
897 """
898 self.__runWmctrl(["-r", title, "-b" + action + ',' + prop])
899
901 """
902 Get the geometry of the currently active window
903
904 Usage: C{window.get_active_geometry()}
905
906 @return: a 4-tuple containing the x-origin, y-origin, width and height of the window (in pixels)
907 @rtype: C{tuple(int, int, int, int)}
908 """
909 active = self.mediator.interface.get_window_title()
910 result, output = self.__runWmctrl(["-l", "-G"])
911 matchingLine = None
912 for line in output.split('\n'):
913 if active in line[34:].split(' ', 1)[-1]:
914 matchingLine = line
915
916 if matchingLine is not None:
917 output = matchingLine[14:].split(' ')[0:3]
918 return map(int, output)
919 else:
920 return None
921
923 p = subprocess.Popen(["wmctrl"] + args, stdout=subprocess.PIPE)
924 retCode = p.wait()
925 output = p.stdout.read()[:-1]
926
927 return (retCode, output)
928
929
931 """
932 Provides access to the internals of AutoKey.
933
934 Note that any configuration changes made using this API while the configuration window
935 is open will not appear until it is closed and re-opened.
936 """
937
938 - def __init__(self, configManager, runner):
939 self.configManager = configManager
940 self.runner = runner
941
943 """
944 Retrieve a folder by its title
945
946 Usage: C{engine.get_folder(title)}
947
948 Note that if more than one folder has the same title, only the first match will be
949 returned.
950 """
951 for folder in self.configManager.allFolders:
952 if folder.title == title:
953 return folder
954 return None
955
957 """
958 Create a text phrase
959
960 Usage: C{engine.create_phrase(folder, description, contents)}
961
962 A new phrase with no abbreviation or hotkey is created in the specified folder
963
964 @param folder: folder to place the abbreviation in, retrieved using C{engine.get_folder()}
965 @param description: description for the phrase
966 @param contents: the expansion text
967 """
968 p = model.Phrase(description, contents)
969 folder.add_item(p)
970 self.configManager.config_altered()
971
973 """
974 Create a text abbreviation
975
976 Usage: C{engine.create_abbreviation(folder, description, abbr, contents)}
977
978 When the given abbreviation is typed, it will be replaced with the given
979 text.
980
981 @param folder: folder to place the abbreviation in, retrieved using C{engine.get_folder()}
982 @param description: description for the phrase
983 @param abbr: the abbreviation that will trigger the expansion
984 @param contents: the expansion text
985 @raise Exception: if the specified abbreviation is not unique
986 """
987 if not self.configManager.check_abbreviation_unique(abbr, None):
988 raise Exception("The specified abbreviation is already in use")
989
990 p = model.Phrase(description, contents)
991 p.modes.append(model.TriggerMode.ABBREVIATION)
992 p.abbreviation = abbr
993 folder.add_item(p)
994 self.configManager.config_altered()
995
996 - def create_hotkey(self, folder, description, modifiers, key, contents):
997 """
998 Create a text hotkey.
999
1000 Usage: C{engine.create_hotkey(folder, description, modifiers, key, contents)}
1001
1002 When the given hotkey is pressed, it will be replaced with the given
1003 text. Modifiers must be given as a list of strings, with the following
1004 values permitted:
1005
1006 <ctrl>
1007 <alt>
1008 <super>
1009 <shift>
1010
1011 The key must be an unshifted character (i.e. lowercase)
1012
1013 @param folder: folder to place the abbreviation in, retrieved using C{engine.get_folder()}
1014 @param description: description for the phrase
1015 @param modifiers: modifiers to use with the hotkey (as a list)
1016 @param key: the hotkey
1017 @param contents: the expansion text
1018 @raise Exception: if the specified hotkey is not unique
1019 """
1020 modifiers.sort()
1021 if not self.configManager.check_hotkey_unique(modifiers, key, None):
1022 raise Exception("The specified hotkey and modifier combination is already in use")
1023
1024 p = model.Phrase(description, contents)
1025 p.modes.append(model.TriggerMode.HOTKEY)
1026 p.set_hotkey(modifiers, key)
1027 folder.add_item(p)
1028 self.configManager.config_altered()
1029
1031 """
1032 Run an existing script using its description to look it up
1033
1034 Usage: C{engine.run_script(description)}
1035
1036 @param description: description of the script to run
1037 @raise Exception: if the specified script does not exist
1038 """
1039 targetScript = None
1040 for item in self.configManager.allItems:
1041 if item.description == description and isinstance(item, Script):
1042 targetScript = item
1043
1044 if targetScript is not None:
1045 self.runner.execute(targetScript, "")
1046 else:
1047 raise Exception("No script with description '%s' found" % description)
1048