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.
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.
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.
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.
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.
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.
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:
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.
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:
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.
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.
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:
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.
make new data column at end of data columns of theDataSource
Or
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:
delete data row 1 of theDataSource
Or
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:
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.
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