What is wrong here?!
tell application "Mail"
set newRule to make new rule at end of rules with properties {name:"OutOFoffice", reply text:"I am out of office"}
tell newRule
make new rule condition at end of rule conditions with properties {rule type:message content, qualifier:does not contain value, expression:"I am out of office"}
end tell
end tell
here is the result I got
enter image description here
I am able to do the opposite but this is what I want
Sometimes—for no clear reason and with no means to predict ahead of time1 those for which this is true—some properties of an element being newly created (by way of the make command) can be set at the point of creation, i.e. assigned through the with properties parameter, but some cannot.
A similarly frustrating situation is exemplified with Finder where
tell application id "com.apple.Finder" to make ¬
Finder window with properties {target:¬
disk "data", bounds:{0, 0, 1440, 800}}
will make you a new Finder window pointed at somewhere that isn't where you want, positioned and sized however it feels. Both the target and bounds property have to set after creation2.
There's no good reason why this should be the case, a conclusion one can arrive at for much of AppleScript's "feature set".
Anyway, hopefully you'll have foreshadowed that the solution to your problem is to set the property in question after creation. Here's a one-liner just because:
tell application id "com.apple.mail" to tell (make new rule with properties ¬
{name:"Out of Office", reply text:"I am out of the office"}) to set ¬
qualifier of (make new rule condition with properties {rule type:¬
message content, expression:reply text}) to does not contain value
¹This is AppleScript's tagline.
²Finder's make command has a to parameter that allows the target to be set at creation.
As CJK points out: You have to set the qualifier after the creation of the rule. See my script for example:
use AppleScript version "2.4" -- Yosemite (10.10) or later
set theProperties to {}
tell application id "com.apple.mail" -- Mail.app
set theMessages to the selection
repeat with i in theMessages
set the end of theProperties to sender of i
end repeat
tell rule "SPAM DELETE"
repeat with i in theProperties
set qualifier of (make rule condition at end of rule conditions with properties {rule type:from header, expression:i}) to does not contain value
end repeat
end tell
end tell
This line the solution:
set qualifier of (make rule condition at end of rule conditions with properties {rule type:from header, expression:i}) to does not contain value
Related
Using Xcode 5.* for a cocoa-applescript automator action.
Interface is a a simple popup menu that gets populated using an outlet with:
tell thePopupMenu to removeAllItems()
tell thePopupMenu to addItemsWithTitles_(theList)
When the action is used in a workflow (a Service actually), I want the next time it is run and the action dialog shows up (I will have "Options:Show when run" selected), I want the popup menu to change the selection to the last one that was selected. Right now, the default first item shows, even though last time it was run, the user selected a different item in the popup menu.
My thought was that I need to capture a change in the popup menu with a Sent Action handler, and then set some type of default. I have a working handler:
on thePopupMenuSentAction_(sender)
set popupValue to (popupSelectedValue of my parameters()) as string
-- save this selection somewhere???
end
What's the right way to save this? Do I use User Defaults? My Bindings are currenly all tied through Parameter object/controller. If I should use User Defaults, can someone give example code for setting up User Defaults, and then how to get and set a new value using Cocoa-Applescript?
If I can get the name string of the menu item saved somewhere, I can get the string and then change the selection of the popup menu in the
on opened {}
-- set up the action interface
end
handler which gets called just before the action is displayed each time.
Thanks for any help,
Joe
I did mine a bit differently. I will assume you are referring to what XCode calls a "pop up button" (somewhat misleading). I did not use the parameters at all, although that is probably better for larger projects. Have a look at the code:
script Insert_Picture_into_Powerpoint_Slide_Show
property parent : class "AMBundleAction"
property menuChoices : {"Insert a Beginning", "Insert at End"}
property menuSelection : missing value
if (menuSelection as string) is "missing value"
set menuSelection to 0 as integer -- sets default value
end if
end script
I bound Content Values to File's Owner and under Model Key Path I put menuChoices.
Then you just bind the Selected Index to File's Owner and for the Model Key Path type menuSelection.
Defaults
On the initial run, if the user does not click anything, the menuSelection will be missing value. Because I couldn't find a way around this, I created a conditional which tests for this and sets it to the first choice by default (the one that is shown when you add the action).
When the user selections one of the menu choices, the choice is remembered on sequential runs.
I'm trying to send html email from Cocoa app, through Mail.app. I want to open new message in Mail.app, include subject, recipient and add HTML Body with links and other content. But can't find the way to do this.
I already tried Scripting Bridge, but MailOutgoingMessage class doesn't have content type i can add content in plaintext.
tried AppleScript, something like this:
set htmlContent to read "/Path/index.html"
set recipientList to {"mail#mail.com"}
tell application "Mail"
set newMessage to make new outgoing message with properties {subject:"qwerty", visible:true}
tell newMessage
make new to recipient at end of to recipients with properties {address:"mail#s.com"}
set html content to htmlContent
--send
end tell
end tell
this code send email with html, only if I'm changing --send to send. But i need to send letter later, after user made some changes.
To recap the problem: Using AppleScript to create a message with HTML content for interactive editing does not work (as of OS X 10.9.2): the new-message form comes up with an empty body.
This should be considered a bug and I encourage everyone to let Apple know at http://bugreport.apple.com - caveat: the html content message class property is not defined in Mail.sdef, Mail.app's AppleScript dictionary, so assigning HTML may not be officially supported.
There is a workaround, but it ain't pretty:
Create the message invisibly.
Save it as a draft.
Open the draft message, at which point the HTML content will appear.
Implementing this robustly is challenging, because several workarounds are required. The following code tries its hardest, though:
Note: Since the code uses GUI scripting, Access for Assistive Devices must be enabled (via System Preferences > Security & Privacy > Accessibility) for the application running this code (e.g., AppleScript Editor or, if run via osascript, Terminal.app).
# Example values; use `read someFile` to read HTML from a file.
set htmlContent to "<html><body><h1>Hello,</h1><p>world.</p></body></html>"
set recipientList to {"person1#example.com", "person2#example.com"}
set msgSubject to "qwerty"
tell application "Mail"
# Create the message *invisibly*, and assign subject text
# as well as the HTML content.
set newMessage to make new outgoing message with properties ¬
{visible:false, subject:msgSubject, html content:htmlContent}
# Add recipients.
# !! Given the workaround below, this is currently pointless.
tell newMessage
repeat with toRcpt in recipientList
make new to recipient at end of to recipients with properties {address:toRcpt}
end repeat
end tell
# Save the current number of drafts messages.
set draftCountBefore to count messages of drafts mailbox
# !! Save the new message as a *draft* - this is necessary
# for the HTML content to actually appear in the message
# body when we open the message interactively later.
save newMessage
# !! Sadly, it takes a little while for the new message
# !! to appear in the drafts mailbox, so we must WAIT.
set newMessageAsDraft to missing value
repeat with i from 1 to 30 # give up after n * 0.1 secs.
set draftCountNow to (count messages of drafts mailbox)
if draftCountNow > draftCountBefore then
set newMessageAsDraft to message 1 of drafts mailbox
exit repeat
end if
delay 0.1 # sleep a little
end repeat
# Abort, if the draft never appeared.
if newMessageAsDraft is missing value then error "New message failed to appear in the drafts mailbox within the timeout period."
# Open the new message as a *draft* message - this ensures that
# the HTML content is displayed and editable in the message body.
# !! The ONLY solution I found is to use `redirect`, which, unfortunately,
# !! *wipes out the recipients*.
# !! It does, however, ensure that the draft is deleted once the message is sent.
redirect newMessageAsDraft with opening window
# Activate Mail.app and thus the draft message's window.
activate
# !! Since the recipients have been wiped out, we need to
# !! add them again - unfortunately, the only way we can do that is to
# !! *GUI scripting* - simulating invocation of a menu command or
# !! sending keystrokes.
tell application "System Events"
# We must make sure that the target window is active before
# we can perform GUI scripting on it.
set newMessageWindow to missing value
repeat with i from 1 to 30 # give up after n * 0.1 secs.
tell (first window of (first process whose frontmost is true) whose subrole is not "AXFloatingWindow")
if name is msgSubject then
set newMessageWindow to it
exit repeat
end if
end tell
delay 0.1 # sleep a little
end repeat
if newMessageWindow is missing value then error "New message failed to become the active window within the timeout period."
# Turn the list of recipients into comma-delimited *string* for pasting into the To field.
set {orgTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {","}}
set recipientListString to (recipientList as text)
set AppleScript's text item delimiters to orgTIDs
# Save the current clipboard content.
set prevClipboardContents to the clipboard
# Cursor is in the "To:" field, so use GUI scripting to send the Edit > Paste command now.
# NOTE: Access for assistive devices must be enabled via System Preferences > Security & Privacy > Accessibility.
set the clipboard to recipientListString
my pasteFromClipboard("")
# Restore the previous clipboard content.
# !! We mustn't do this instantly, as our temporary content may not have
# !! finished pasting yet. It would be non-trivial to determine
# !! when pasting has finished (examining `count of to recipients` doesn't work),
# !! so we take our chances with a fixed, small delay.
delay 0.1
set the clipboard to prevClipboardContents
# Place the cursor in the message *body*.
# !! This works as of Mail.app on OS X 10.9.2, but may break in the future.
try
tell newMessageWindow
tell UI element 1 of scroll area 1
set value of attribute "AXFocused" to true
end tell
end tell
end try
end tell
end tell
(*
Pastes form the clipboard into the active window of the specified application (process) using GUI scripting
rather than keyboard shortcuts so as to avoid conflicts with keyboard shortcuts used to invoke this handler.
Specify "" or `missing value` to paste into the currently active (frontmost) application.
The target process may be specified by either name or as a process object.
CAVEAT: While this subroutine IS portable across *UI languages*, it does make an assumption that will hopefully hold for
all applications: that the "Edit" menu is the *4th* menu from the left (Apple menu, app menu, File, Edit).
Examples:
my pasteFromClipboard("") # paste into frontmost app
my pasteFromClipboard("TextEdit")
*)
on pasteFromClipboard(targetProcess)
tell application "System Events"
if targetProcess is missing value or targetProcess = "" then
set targetProcess to first process whose frontmost is true
else
if class of targetProcess is text then
set targetProcess to process targetProcess
end if
-- Activate the application (make it frontmost), otherwise pasting will not work.
set frontmost of targetProcess to true
end if
tell menu 1 of menu bar item 4 of menu bar 1 of targetProcess
-- Find the menu item whose keyboard shortcut is Cmd-V
set miPaste to first menu item whose value of attribute "AXMenuItemCmdChar" is "V" and value of attribute "AXMenuItemCmdModifiers" is 0
click miPaste
end tell
end tell
end pasteFromClipboard
It isn't clear what your are looking for, but I'll do my best to offer some help.
If you leave send commented, then the message should already be open in Mail.app, waiting for further editing and sending.
By adding the line save newMessage, it will be saved to the drafts folder. The user can open it and continue editing whenever they please. If you want to actually send the draft from your application, use:
set sendMessage to first message of drafts mailbox
send sendMessage
Good luck!
I didn't see that you needed to edit the message before sending, so my previous answer was wrong. This time it should be correct.
It basically
takes a preformatted RTF file,
renders it & puts it into the clipboard,
creates a new message,
fills in the fields,
moves the focus to the message body,
pastes the formatted clipboard
Here is the code:
set textSubject to "HTML Test"
set toAddress to "john.doe#gmail.com"
set toName to "John Doe"
tell application "Mail"
do shell script "cat ~/Documents/RTF\\ File.rtf | textutil -stdin -stdout -convert rtf | pbcopy"
set refMessage to make new outgoing message with properties {name:toName, address:toAddress, subject:textSubject, visible:true}
tell refMessage
make new to recipient at end of to recipients with properties {name:toName, address:toAddress}
end tell
end tell
tell application "System Events"
tell application process "Mail"
set frontmost to true
set value of attribute "AXFocused" of scroll area 4 of window textSubject to true
end tell
keystroke "v" using {command down}
end tell
Again, this worked fine on Snow Leopard
Hope that helped.
Once a record has been saved to the database, I want to have any field change color to indicate that the user has made uncommitted changes if they type into that field.
Is it best to just set the foreColor on closeField, or is it better to track each keypress, and compare it against a variable containing the previous field content?
Are you asking how to detect a text change once a process that loaded field data has been made, and new, unsaved data is being entered? You mentioned new uncommitted changes, and I am not sure what you have in mind. This means that using a closeField handler will not indicate "uncommitted changes if they type into that field"
If so, however, I would set a custom property of the field upon writing to the database, and put a simple handler in the field script
on textChanged
if me <> the lastText of me then set the foreColor of me to "blue"
end textChanged
The property is named "the lastText", and is set by whatever handler saves to the database.
set the lastText of field "yourField" to field "yourField"
The color will change to blue if anything is edited within that field. Of course, the saving handler ought as well to set the color back to black.
Here's a card level script to handle all the fields on a form. When you load the data on to the card, set each field's uOriginalText custom property to the same value as the text loaded into the field.
on closeField
# the target control for this message
put the target into tTarget
# detect case changes like 'mr jobs' to 'Mr Jobs'
set the caseSensitive to true
# compare with the original text, set when the form was loaded
if the text of tTarget <> the uOriginalText of tTarget then
# indicate the change - I've used backColor in case the field is now empty
set the backColor of tTarget to "red"
else
# clear warning background color
set the backColor of tTarget to empty
end if
end closeField
In glx2 we actually do a bit of overkill - save the md5digest of the field when you save it, then check the md5digest of the field against the saved value to see if it needs saving. Obviously you don't want to do the computation on each keypress, no matter how fast it is. Doing that on closeField is a good way to deal with it, although I seem to remember having a problem in the past with closeField not getting triggered if you click onto another app on OSX.
I'm attempting to script BBEdit to make me feel more at home in coming from TextMate. One thing I need to be able to do is see if an object I have a reference to has a particular property.
For instance:
tell application "BBEdit"
tell front window
get selected items
end tell
end tell
This will succeed on a project window, but not on a disk browser window, because the latter does not have a 'selected items' property. How do I see if there is such a property in the object?
Please note: I know how to inspect an object in Script Editor (get properties) to see what properties it has, but I need to know at runtime what they are.
What about the class?
tell application "BBEdit"
if class of window 1 is disk browser window then
# ...
else
# ...
end if
end tell
I don't have bbedit so I can't check, but if different types of windows exist, and each type of window has different properties, then can't you just check the window type first? Then you would know what type of properties you can get. There must be some basic property of a window that tells you its type or kind or whatever that would help you make the decision.
The only solution I have so far is to wrap it in an error handler:
try
set sel to selected items
on error errMsg number errNum
if errNum is -1700 then
-- Code that handles no selected items attribute
return
end
error errMsg number errNum
end try
-- Code that handles when selected items attribute exists
There is a difference between documents and windows in BBEdit. Windows are an element of documents, but only windows have the selection property, so you can check the type of window first and avoid catching errors entirely (and make for cleaner code as a result).
Also, try using the selection property, which is hard property in BBEdit as opposed to "selected items" because selection will always return a usable object, even if only an insertion point.
I want to delete the text present in the Java Edit box and want to add a new Text into that feild.
How can i perform this task in QTP (Scripting)?
#TestGeek
If you want to use "ctl+A and delete" sequence, use .Type() method of Edit object.
If your object is not fully supported by QTP and does not have .Type() method, you can use WshShell.SendKeys() as a workaround (don't forget to set focus on the object first).
In QTP, constants are defined with "mic" (Mercury Integer Constant) prefix. You can search for the full list in help.
For those, that you mentioned, you need the following:
micCtrlDwn
"A"
micCtrlUp
micDel
Try using the objects native function setText(""). This resets the contents to an empty string. The advantage is that is does the job in 1 line.
The .object allows access to the native methods, and a tooltip with all methods will appear in the qtp IDE only if the UI object is actually open on the screen.
JavaWindow("win").JavaInternalFrame("frame").JavaEdit("edit").Object.setText("")
I'm not very familiar with the Java add in but AFAIK the Set method replaces the text. If you really need to clear it first you can set to the empty string.
JavaWindow("win").JavaEdit("box").Set "" ''# Clear old text (optional)
JavaWindow("win").JavaEdit("box").Set "new value"