Guest
2010-09-11, 05:53 AM
The code below (and the attached script version with icon) is a simple illustration of OF 1.8's new ability to conserve memory of state between successive runs of a script on the OF toolbar.
This example does two things:
- It acts as a 'Home Page' button, combining Perspectives > All Items with View > Show All Projects allowing you to jump back with one click to a window where all your data is in view (creating the window if necessary).
- It remembers the View Mode, Focus, Filter Settings, Selections, and Search Term of where you came from. If you click it a second time it foregrounds a window displaying that view (creating a new window if necessary).
In short, a sort of toggle between 'Home' and 'Away', using Applescript 'global' variables, which retain their value between runs, to remember the 'Away' settings.
(Intended to ease some of the friction involved in alternating between a focused view and a broader view of what you are up to.)
Code:
-- HOME page TOGGLE: a home button with memory (Clears focus and returns to default view, or returns to last remembered NON-HOME view)
-- Rob Trew ver 0.12
-- If the front window is does NOT show a broad "home page view",
-- jump to the first window that does (or create one if necessary).
-- If the front window DOES show a broad "home page view" then,
-- do we remember the last NARROWED view in which this button was used ?
-- if we do, jump to the first window that shows that narrowed view, or
-- create a new window in which to show that view.
-- ver 0.12 : fix for bug involving loss of reference to a window whose visibility is changed
property pblnRestoreSearch : true -- Restore any search term when returning to an 'Away' view ?
-- DEFINE THE HOME VIEW
--property pstrDefaultPerspective : "" -- There is a BUG (OF 1.8) in the reading and clearing of the
-- 'perspective name' property, so we have to bypass the perspective system in this script entirely
property pstrDefaultViewMode : "project"
property plstDefaultFilters : {"remaining", "none", "none", "incomplete", "all", "any"}
-- DECLARE SOME VARIABLES WHOSE VALUES SHOULD PERSIST ACROSS RUNS OF THE SCRIPT
--global gstrPerspective
global gstrViewMode
global glstFocus
global glstFilters
global glstSideSeln
global glstContentSeln
global gstrSearchTerm
on run
-- DO THE GLOBALS ALL RETAIN A VALUE FROM A PREVIOUS RUN ?
try
--gstrPerspective
gstrViewMode
glstFocus
glstFilters
glstSideSeln
glstContentSeln
gstrSearchTerm
on error -- IF NOT, THEN SET THEM ALL TO DEFAULTS
--set gstrPerspective to pstrDefaultPerspective
set gstrViewMode to pstrDefaultViewMode
set glstFocus to {}
set glstFilters to plstDefaultFilters
set glstSideSeln to {}
set glstContentSeln to {}
set gstrSearchTerm to ""
end try
-- GET A REFERENCE TO THE FRONT WINDOW (CREATING IT IF NOTHING THERE)
tell application id "com.omnigroup.omnifocus"
set oDoc to default document
if (count of document windows of oDoc) < 1 then
tell oDoc
set oWin to make new document window
end tell
else
set oWin to front document window of oDoc
end if
tell oWin
if not visible then set visible to true
end tell
-- We need to get the reference again because switching visibility tends to lose it.
set oWin to front document window of oDoc
-- GET THE SETTINGS OF THE FRONT WINDOW
tell oWin
--set strPerspective to my GetPerspective(oWin)
set strViewMode to selected view mode identifier
set lstFocus to {}
if my IsNarrowed(focus) then
repeat with oObject in focus
set {cClass, strID} to {class, id} of oObject
set end of lstFocus to {cClass, strID}
end repeat
end if
set lstFilters to my GetFilters(oWin)
set blnSearchClear to true
try
set blnSearchClear to (search term = "")
end try
end tell
-- IS THIS A HOME VIEW (AS DEFINED BY THE SCRIPT PROPERTIES) ?
set blnHomeView to (strViewMode = pstrDefaultViewMode)
--set blnHomePerspective to (strPerspective = pstrDefaultPerspective)
set blnHomeFocus to (lstFocus = {})
set blnHomeFilter to (lstFilters = plstDefaultFilters)
set blnAtHome to (blnHomeView and blnHomeFocus and blnHomeFilter and blnSearchClear)
-- IF THIS A HOME VIEW ...
if blnAtHome then
-- DO WE REMEMBER ANY NARROWER VIEW ?
if (gstrViewMode ≠ pstrDefaultViewMode) or (glstFocus ≠ {}) or ¬
(glstFilters ≠ plstDefaultFilters) or (not blnSearchClear) then
-- IF SO, TRY TO RESTORE THE REMEMBERED NARROWER VIEW,
-- EITHER BY FINDING A WINDOW WHICH DISPLAYS IT,
set lstDocWins to document windows of oDoc
set blnFound to false
repeat with oWin in lstDocWins
if my matchesview(oWin, {gstrViewMode, glstFocus, glstFilters}) then
set oWin to my BringToFront(oWin)
set blnFound to true
end if
end repeat
-- OR BY RE-CREATING THE NARROWER VIEW IN A NEW WINDOW.
if not blnFound then
tell oDoc
set oWin to make new document window
end tell
if selected view mode identifier of oWin is not gstrViewMode then ¬
set selected view mode identifier of oWin to gstrViewMode
my RestoreSelns(oWin, glstSideSeln, glstContentSeln)
my RestoreFocus(oWin, glstFocus)
my SetFilters(oWin, glstFilters, (gstrViewMode = "context"), "")
if pblnRestoreSearch then set search term of oWin to gstrSearchTerm
end if
if pblnRestoreSearch then set search term of oWin to gstrSearchTerm
end if
else -- IF THIS IS NOT A HOME VIEW
-- RECORD THE SETTINGS WHICH WE READ EARLIER
--set gstrPerspective to strPerspective
set gstrViewMode to strViewMode
set glstFocus to lstFocus
set glstFilters to lstFilters
-- AND A COUPLE OF ADDITIONAL ONES
set oWin to front document window of oDoc
tell oWin
set glstSideSeln to {id, name} of selected trees of sidebar
set glstContentSeln to {id, name} of selected trees of content
set gstrSearchTerm to ""
try
set gstrSearchTerm to search term
end try
end tell
-- FOREGROUND ANY EXISTING HOME VIEW WINDOW
set lstDocWins to document windows of oDoc
repeat with oWin in lstDocWins
if my matchesview(oWin, {pstrDefaultViewMode, {}, plstDefaultFilters}) then
set oWin to my BringToFront(oWin)
return
end if
end repeat
-- OR MAKE A NEW HOME VIEW WINDOW IF NECESSARY
tell oDoc
set oWin to make new document window
if selected view mode identifier of oWin is not pstrDefaultViewMode then ¬
set selected view mode identifier of oWin to pstrDefaultViewMode
my SetFilters(oWin, plstDefaultFilters, (pstrDefaultViewMode = "context"), "")
tell oWin
set focus to {}
tell sidebar
select tree 2
end tell
end tell
end tell
end if
end tell
end run
on RestoreFocus(oWin, glstFocus)
using terms from application "OmniFocus"
try -- glstFocus may not be defined
set lstOldFocus to {}
repeat with oObject in glstFocus
set {cClass, strID} to oObject
try -- (they might have been deleted in the meanwhile)
if cClass is project then
set oObj to project id strID of oDoc
else
set oObj to folder id strID of oDoc
end if
set end of lstOldFocus to oObj
end try
end repeat
set focus to lstOldFocus
end try
end using terms from
end RestoreFocus
on SetFilters(oWin, {strSmartGroup, strGrouping, strSorting, strState, strFlagged, strDurn}, blnContextView, strComment)
if blnContextView then
set strClass to "-contexts"
else
set strClass to "-projects"
end if
tell application id "com.omnigroup.omnifocus"
tell oWin
if strSmartGroup is not "" then
if strSmartGroup is not "-" then if selected smart group identifier of sidebar is not strSmartGroup then ¬
set selected smart group identifier of sidebar to strSmartGroup & strClass
else
set selected smart group identifier of sidebar to "all" & strClass
end if
tell content
try
if strGrouping is not "" then
if strGrouping is not "-" then if selected grouping identifier is not strGrouping then ¬
set selected grouping identifier to strGrouping
else
set selected grouping identifier to "none"
end if
on error
my CheckIdentifier("grouping", strGrouping, strComment)
end try
try
if strSorting is not "" then
if strSorting is not "-" then if selected sorting identifier is not strSorting then ¬
set selected sorting identifier to strSorting
else
if blnContextView then
set selected sorting identifier to "context"
else
set selected sorting identifier to "none"
end if
end if
on error
my CheckIdentifier("sorting", strSorting, strComment)
end try
try
if strState is not "" then
if strState is not "-" then if selected task state filter identifier is not strState then ¬
set selected task state filter identifier to strState
else
set selected task state filter identifier to "all"
end if
on error
my CheckIdentifier("task state filter", strState, strComment)
end try
try
if strFlagged is not "" then
if strFlagged is not "-" then if selected task flagged filter identifier is not strFlagged then ¬
set selected task flagged filter identifier to strFlagged
else
set selected task flagged filter identifier to "all"
end if
on error
my CheckIdentifier("task flagged filter", strFlagged, strComment)
end try
try
if strDurn is not "" then
if strDurn is not "-" then if selected task duration filter identifier is not strDurn then ¬
set selected task duration filter identifier to strDurn
else
set selected task duration filter identifier to "any"
end if
on error
my CheckIdentifier("task duration filter", strDurn, strComment)
end try
end tell
end tell
end tell
end SetFilters
on CheckIdentifier(strIdentifier, strSetting, strComments)
display dialog "Unknown " & strIdentifier & " identifier: " & return & return & quote & strSetting & quote & ¬
return & return & "Correct and try again." buttons {"OK"}
end CheckIdentifier
on matchesview(oWin, {strViewMode, lstFocus, lstFilters})
using terms from application "OmniFocus"
tell oWin
if selected view mode identifier = strViewMode then
if my GetFilters(oWin) = lstFilters then
set blnNarrowed to my IsNarrowed(focus of oWin)
set lngFocus to length of lstFocus
if lngFocus > 0 then
set lstWinFocus to {}
set iObj to 0
repeat with oObject in focus
set iObj to iObj + 1
if iObj > lngFocus then return false
set end of lstWinFocus to {class, id} of oObject
end repeat
return (lstFocus = lstWinFocus)
else
return not blnNarrowed
end if
end if
end if
return false
end tell
end using terms from
end matchesview
on IsNarrowed(oFocus)
using terms from application "OmniFocus"
repeat with oObj in oFocus
return true
end repeat
return false
end using terms from
end IsNarrowed
on GetFilters(oWin)
tell application "OmniFocus"
set strSmartGroup to selected smart group identifier of sidebar of oWin
set my text item delimiters to "-"
set lstParts to text items of strSmartGroup
set strSmartGroup to (items 1 thru ((length of lstParts) - 1) of lstParts) as string
set my text item delimiters to space
tell content of oWin
{strSmartGroup, ¬
selected grouping identifier, selected sorting identifier, ¬
selected task state filter identifier, selected task flagged filter identifier, ¬
selected task duration filter identifier}
end tell
end tell
end GetFilters
on BringToFront(oWin)
tell application "OmniFocus"
set lngWin to id of oWin
set visible of oWin to false
set oWin to window id lngWin
set visible of oWin to true
return window id lngWin
end tell
end BringToFront
on RestoreSelns(oWin, glstSideSeln, glstContentSeln)
tell application "OmniFocus"
tell oWin
-- Try to restore the remembered sidebar selection
try
tell sidebar
select {}
set {lstID, lstName} to glstSideSeln
repeat with iSeln from 1 to length of lstID
set strID to item iSeln of lstID
if strID is missing value then
set strTreeOne to "Library"
if gstrViewMode is "context" then set strTreeOne to "Contexts"
if item iSeln of lstName is strTreeOne then
select tree 2 with extending
else
select tree 1 with extending
end if
else
try
select descendant tree id strID with extending
end try
end if
end repeat
end tell
end try
-- Try to restore the remembered content selection
try
tell content
select {}
set {lstID, lstName} to glstContentSeln
repeat with iSeln from 1 to length of lstID
set strID to item iSeln of lstID
if strID is missing value then
set strNAme to item iSeln of lstName
if name is not missing value then
set oTree to (first descendant tree where name is strNAme)
select oTree with extending
end if
else
try
select descendant tree id strID with extending
end try
end if
end repeat
end tell
end try
end tell
end tell
end RestoreSelns
Last edited by RobTrew; 2011-07-05 at 07:46 AM..
|