Saturday, December 16, 2017
  • Index
  •  » unScripted
  •  » Getting Started with AppleScript Studio - Table Views

#1 2006-10-09 06:01:20 am

Ben Waldie
Member
From:: Phoenixville, PA
Registered: 2003-08-25
Posts: 18
Website

Getting Started with AppleScript Studio - Table Views

By Ben Waldie

In this month's column, we're going to discuss a specific type of interface element that is often incorporated into AppleScript Studio projects' a table view. Table views consist of one or more cells (displayed using columns and rows), which may be used to display data. Think of a table view as being similar in layout to a worksheet in Excel. See figure 1 for an example of a 2-column table view in an AppleScript Studio project's interface.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-1-lg.gif

Figure 1. A Table View in AppleScript Studio


Table views may be configured in a variety of ways via Interface Builder's Inspector palette, depending on the exact needs of your specific project. For example, table views may be configured to display or hide their column headers, allow cells to be user editable, allow rows and columns to be resized and re-arranged, allow multiple selections, allow empty selections, and more. Cells within table views may even contain other types of interface elements, including checkboxes, popup buttons, text fields, and more.

How Table Views Work

Interface Builder itself does not provide a direct mechanism for populating table views with data within an AppleScript Studio project. This must actually be done via the AppleScript code within the project. We'll get to this shortly. First, let's talk briefly about how table views work.

Contrary to how they appear, table views don't actually contain data themselves. Rather, table views are linked to data sources, which will contain the data. Table views are used to visually display the data within an associated data source. Data sources consist of data columns, data rows, and data cells. A data cell is essentially the intersection of a data row with a specific data column. For example, if a data source has two data columns, then each data row within the data source will contain two data cells, one for each column. Think of a data source as being kind of like a mini-database within the memory of your running AppleScript Studio project.

Adding a Table View to an Interface

The table view interface element may be found in the Cocoa Data Views palette in Interface Builder. To add it to an interface, drag it from the palette to the desired location on a window, panel, or drawer. While the table view is selected in the interface, you may modify its various attributes, such as the number of columns, the row height, and more, using the Inspector palette. See figure 2.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-2-lg.gif

Figure 2. Table View Attributes


If you are working with multiple table views within an interface, you may want to apply AppleScript names to the table views, as you might do to other elements within your project's interface. This may be done via the AppleScript pane in the Inspector palette, and doing so will allow you to more easily differentiate between table views throughout your AppleScript code, ensuring that the correct one is being targeted.

Note that, after selecting a table view in an interface, the AppleScript pane in the Inspector palette will actually reference a scroll view. See figure 3. You can assign an AppleScript name to a scroll view, if desired.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-3-lg.gif

Figure 3. A Scroll View in AppleScript Studio


In AppleScript Studio, table views are contained within scroll views. Double click on the scroll view to select the actual table view. See figure 4. You can assign an AppleScript name to a table view, if desired.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-4-lg.gif

Figure 4. A Table View in AppleScript Studio


Within a table view, you may also choose to select individual table columns, and assign AppleScript names to them, if desired. See figure 5.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-5-lg.gif

Figure 5. Table Columns in AppleScript Studio


When working with table views, think of each element above as an individual interface element within a hierarchy. A scroll view contains a table view, which contains table columns. In your AppleScript code, you will target these interface elements within their interface hierarchy, for example table view 1 of scroll view 1 of window 1. Like any other interface element, each of these elements possesses its own attributes (check out the AppleScript Studio Terminology reference for a detailed overview of scriptable attributes for these elements), as well as various event handlers, which may be linked to the element, depending on the needs of your project.

Preparing to Follow Along

To follow along with the examples in this month's column, you will need to create an AppleScript Studio project. Launch Xcode, and select New Project from the File menu. Next, select the AppleScript Application project template, and create a new project named Table Example.

Once the project has been created, double click on the MainMenu.nib component to open the project's interface in Interface Builder. Next, design the main window of the project to match the example window shown in figure 6, below.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-6-lg.gif

Figure 6. Table View Example Interface


Next, assign AppleScript names and clicked event handlers to the buttons on the interface. Assign the name add to the + button, the name remove to the - button, and the name reveal to the Reveal button. Link the clicked event handler for each of these buttons to the main script in your project. Finally, link the will open event handler for the window itself to the main script in your project.

Populating a Table View's Data Source

You may have noticed that, in designing the interface above, we did not create a data source for our table view. Data sources can be manually inserted and linked to table views in Interface Builder. However, the release of AppleScript Studio 1.4 with Mac OS X 10.4 Tiger has virtually eliminated the need to do this. Beginning with AppleScript Studio 1.4, we can now set the content property of a table view to a list containing values, a list of lists containing values, or a list of records containing fields and values. Doing so will automatically create a data source (if it does not already exist) for the targeted table view, and insert and populate the appropriate number of data rows and columns, based on the data specified. Let's take a look at this in more detail.

Suppose we are working with a single column table view, or suppose we only want to populate the first column of a multi-column table view. To do this, we can set the contents of the table view to a list of individual values. For example:

Applescript:

set content of table view 1 of scroll view 1 of window 1 to {"Macintosh HD", "Users", "bwaldie"}

See figure 7 for an example of how a table view would appear, after executing the code above.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-7-lg.gif

Figure 7. Populating a Single Table Column Using a List


Now, suppose we want to populate both columns of a two-column table. This can be done by setting the content property of the table view to a list of two-item lists. For example:

Applescript:

set content of table view 1 of scroll view 1 of window 1 to {{"Macintosh HD", "Macintosh HD:"}, {"Users", "Macintosh HD:Users:"}, {"bwaldie", "Macintosh HD:Users:bwaldie:"}}

Figure 8 shows an example of how a table view would appear, after executing the code above.

http://files.macscripter.net/unscripted/110606-Waldie/110606-Waldie-8-lg.gif

Figure 8. Populating Multiple Table Columns Using a List of Lists


The following code will essentially perform the same function as the previous example. However, it is done using a list of records containing field names and values, rather than a list of lists. Notice that the field names specified in each record correspond to the AppleScript names that we applied to the table columns in our interface.

Applescript:

set content of table view 1 of scroll view 1 of window 1 to {{|name|:"Macintosh HD", |path|:"Macintosh HD:"}, {|name|:"Users", |path|:"Macintosh HD:Users:"}, {|name|:"bwaldie", |path|:"Macintosh HD:Users:bwaldie:"}}

Creating a Data Source

It is possible to write code to create a data source and link it to a table view manually, rather than allowing this to be done dynamically. To do this, first use the make command to create the data source. Then, set the data source of the table view to reference the newly created data source. For example:

Applescript:

set theDataSource to make new data source at end
set data source of table view 1 of scroll view 1 of window 1 to theDataSource

Adding Columns and Rows

Prior to AppleScript Studio 1.4, it was necessary to write code to build data columns and data rows within a table view's data source. In fact, you may still find situations where you will want to do this. To create a data column or a data row within a data source, use the make command, as demonstrated here.

Applescript:

make new data column at end of data columns of theDataSource

Or

Applescript:

make new data row at end of data rows of theDataSource

Deleting Columns and Rows

Deleting data columns and data rows from a table view's data source is done using the delete command. For example:

Applescript:

delete data row 1 of theDataSource

Or

Applescript:

delete data column 1 of theDataSource

Getting the Selection of a Table View

To access the selection of a table view, reference the selected data row or selected data rows properties of the table view. For example:

Applescript:

selected data row of table view 1 of scroll view 1 of window 1
--> data row id 4 of data source id 2

Pulling Things Together
Now, let's pull together several of the techniques that we have discussed throughout this column. Enter the following example code into the main script of your AppleScript Studio project.

Applescript:

on clicked theObject
   if name of theObject = "add" then
       set theNewFile to choose file without invisibles
       tell data source of table view 1 of scroll view 1 of window 1
           if (count data columns) = 0 then
               repeat 2 times
                   make new data column at end of data columns
               end repeat
           end if
           set theNewRow to make new data row at end of data rows
           set contents of data cell 1 of theNewRow to name of (info for theNewFile)
           set contents of data cell 2 of theNewRow to theNewFile as string
       end tell
   else if name of theObject = "delete" then
       if (count data rows of data source of table view 1 of scroll view 1 of window 1) is greater than 0 then
           set theSelectedRow to selected data row of table view 1 of scroll view 1 of window 1
           delete theSelectedRow
       end if
   else if name of theObject = "reveal" then
       if (count data rows of data source of table view 1 of scroll view 1 of window 1) is greater than 0 then
           set theSelectedRow to selected data row of table view 1 of scroll view 1 of window 1
           set thePath to contents of data cell 2 of theSelectedRow
           tell application "Finder" to reveal alias thePath
       end if
   end if
end clicked

on will open theObject
   set theFolder to choose folder without invisibles
   tell application "Finder"
       set theFiles to every file of theFolder
       set theTableViewContents to {}
       repeat with a from 1 to length of theFiles
           set theCurrentFile to item a of theFiles
           set theCurrentFileName to name of theCurrentFile
           set end of theTableViewContents to {theCurrentFileName, theCurrentFile as string}
       end repeat
   end tell
   set content of table view 1 of scroll view 1 of window 1 to theTableViewContents
end will open

Next, build and run the project. If all goes well, you should be prompted to choose a folder. Next, the project's interface should be displayed, and the table view should be populated with the names and paths of any files that were found within the specified folder. Clicking the + button should prompt you to select a new file to add to the end of the table view. Clicking the button should remove the selected row from the table view. Clicking the Reveal button should display the file that is currently selected in the table view, in the Finder.

If you have any trouble following along, feel free to download a copy of the completed project here.

In Conclusion

You should now have a basic understanding of how to utilize table views in AppleScript Studio projects. For more guidance as you put the practices we have discussed to use, be sure to browse the AppleScript Studio Terminology Reference guide, included in Xcode's documentation and on the Apple Developer Connection website. And, take some time to explore the example projects in the Developer/Examples/AppleScript Studio/ folder, installed with Xcode. Here, you will find numerous fully editable example projects that incorporate table views. Also, feel free to post your AppleScript Studio questions the AppleScript Studio forum on MacScripter's online BBS.

Until next time just script it!

-Ben Waldie


Ben Waldie, Automated Workflows, LLC
AppleScript & Automator Tips & Articles - http://www.automatedworkflows.com/tips/tips.html
Mac Automation Made Simple Video Podcast Series - http://www.automatedworkflows.com/tips/podcast.html
Automator for Mac OS X Visual QuickStart Guide - http://www.automatedworkflows.com/books/books.html


Filed under: Finder, ASS, Studio, Waldie, Tables

Offline

 

#2 2009-04-29 06:21:18 pm

mbs402
Member
From:: Plano, Texas
Registered: 2009-04-07
Posts: 53
Website

Re: Getting Started with AppleScript Studio - Table Views

Ben,

Thanks for the great tutorial...

After looking at the example (2 column) tables, I created 4 columns on the table in the scroll view, but I would like to be able add the columns to the NIB window dynamically.

I tried this below :

Added a fifth column "Flag" to the headers list, and a dummy value of "yes" to the corresponding data value for each row in the loop, but when I built and ran it only the first four data columns displayed.

Applescript:


-- This does not contain all the code, SEE the next script for the complete code I have so far
-- This did not work with the 4 column table while using the "repeat no_of_columns times"

on will open theObject
   set aColumnHeaders to {"SeqNo", "Flag", "Item Name", "Item Class", "Item Path"}
   set aColumnWidths to {60, 80, 180, 120,400}
   set no_of_columns to count aColumnHeaders
   set theDataSource to make new data source at end
   set data source of table view 1 of scroll view 1 of window 1 to theDataSource
   
   repeat no_of_columns times
       make new data column at end of data columns of theDataSource
   end repeat
   
   repeat loop...
       [...]
       set end of theTableViewContents to {counter, "yes", this_name, this_class, this_path}
   end repeat
end will open

The nice thing would be to have a NIB window ->Scroll View -> Table  with a couple of hardcoded columns, and build the remaining columns dynamically as the need arose. I dont want to build a Table with something like 10 fields, in order to use the table to display from 1 to 10 fields.

I am trying to build a dynamic table that I can call from applescript when "choose from list" is not enough. I noticed how you deleted columns dynamically, but did not find how they could be added on the fly.

I was able to :
( 1 ) assign the column headers, and column widths dynamically, but not add extra columns.
( 2 ) Double click on a row, and {open, reveal} the corresponding file/folder/symlink, etc, or take some other action.

As soon as I can figure it out, I would like to do the following :
( 1 ) Setup to allow sorting via the column headers.
( 2 ) Select a row and click a button to trigger an action (this should be fairly simple).
( 3 ) Call this app from a separate applescript, and pass it the 2-dimensional arrays to display in the table. (this might be harder) If I have no other choice I can write the data to a file, that this app looks for when it launches, and it can load the data there. There might be an easier way ?

Any ideas ?

Bill Hernandez
Plano, Texas


Applescript:


-- This contains what I have so far, and is working very well...

on will open theObject
   
   set aColumnHeaders to {"SeqNo", "Item Name", "Item Class", "Item Path"}
   set aColumnWidths to {60, 180, 120,400}
   set no_of_columns to count aColumnHeaders
   set theDataSource to make new data source at end
   set data source of table view 1 of scroll view 1 of window 1 to theDataSource
   
   repeat no_of_columns times
       make new data column at end of data columns of theDataSource
   end repeat
   
   set theFolder to choose folder without invisibles
   tell application "Finder"
       -- set theFiles to every file of theFolder as alias list
       -- set theFiles to every file of the entire contents of theFolder as alias list
       set theFiles to every item of the entire contents of theFolder as alias list        
   end tell
   set theTableViewContents to {}
   
   tell table view 1 of scroll view 1 of window 1
       repeat with counter from 1 to length of aColumnHeaders
           set the content of header cell of table column counter to (item counter of aColumnHeaders) as string
           set the width of table column counter to (item counter of aColumnWidths) as integer
       end repeat
   end tell

   set home_posix_path to POSIX path of (path to home folder from user domain as text)
   set len to count characters of home_posix_path
   if (last character of home_posix_path is equal to "/") then
       -- set len to len - 1
   end if
   set str2match to (characters 1 through len of home_posix_path) as string
   
   repeat with counter from 1 to length of theFiles
       set this_file to item counter of theFiles
       tell application "Finder" to set w_props to get properties of this_file
       set this_name to displayed name of w_props
       set this_class to (class of w_props) as string
       
       if (this_class is equal to "«class alia»") then
           set this_class to "alias"
       else if (this_class is equal to "«class cfol»") then
           set this_class to "folder"
       else if (this_class is equal to "«class docf»") then
           set this_class to "document"
       end if
       
       set this_path to POSIX path of (this_file as string)
       if (str2match is equal to ((characters 1 through len of this_path) as string)) then
           set this_path to "~" & (characters len through -1 of this_path) as string
       end if
       
       set end of theTableViewContents to {counter, this_name, this_class, this_path} -- this_file as string}
   end repeat
   set content of table view 1 of scroll view 1 of window 1 to theTableViewContents
   
end will open

on clicked theObject
   (*Add your script here.*)
   tell window of theObject
       close
   end tell
   tell application of theObject
       quit
   end tell
end clicked

on double clicked theObject
   (*Add your script here.*)
   if name of theObject = "table_view" then
       if ((count data rows of data source of table view 1 of scroll view 1 of window 1) is greater than 0) then
           set theSelectedRow to selected data row of table view 1 of scroll view 1 of window 1
           set thePath to contents of data cell 4 of theSelectedRow
           set thePath to do shell script "echo " & thePath

           -- THESE should be globals so they are only initialized once
           set b1 to "Reveal"
           set b2 to "Open"
           set s to "Which would you prefer ?" & return
           set s to s & "( 1 ) Reveal the item within its parent container." & return
           set s to s & "( 2 ) Open the item (file, or folder, etc)." & return & return

           set which_choice to button returned of (display dialog s buttons {b1, b2} default button {b2})
           
           tell application "Finder"
               activate
               if (which_choice is equal to b1) then
                   reveal POSIX file thePath as alias
                   set w_ref to Finder window 1
                   select w_ref
                   set toolbar visible of w_ref to false
                   set w_props to {bounds:{10, 46, 300, 500}, current view:list view, sidebar width:0, toolbar visible:false, statusbar visible:true}
                   set properties of w_ref to w_props
               else
                   open POSIX file thePath as alias
               end if
           end tell
       end if
   end if
end double clicked

Last edited by mbs402 (2009-04-30 01:50:15 am)

Offline

 
  • Index
  •  » unScripted
  •  » Getting Started with AppleScript Studio - Table Views

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)