Monday, November 08, 2010 at 12:03 AM.
system.verbs.builtins.Frontier.tools.install
on install (f) {
<<Changes:
<<9/17/10; 11:30:03 PM by DW
<<If user.tools.prefs.flUseScheduler2 is true, install the scheduled script in user.scheduler2 and delete the links in user.scheduler (so the scripts only run once).
<<06/24/02; 3:05:44 PM by JES
<<If a Tool's suite has a localization sub-table, register the languages in the appropriate localization sub-table(s).
<<06/12/02; 12:13:04 AM by JES
<<Install callbacks in the user.radio.callbacks table, if the Tool has callbacks at toolSuite.callbacks.radio, and user.radio.callbacks is defined.
<<03/07/02; 12:02:37 AM by JES
<<Call scheduler.monitorThreads after installing the Tool, to kick off its thread (if it exists).
<<12/01/01; 6:34:14 PM by JES
<<Fixed a bug installing Tools windowTypes in the user.tools.windowTypes table.
<<11/30/01; 5:04:11 PM by JES
<<Install windowTypes and noteTypes addresses inside a try statement, so that installation won't fail if there's already a table at the address.
<<11/29/01; 5:12:36 PM by JES
<<Fixed a bug installing windowTypes.
<<11/26/01; 10:58:48 PM by JES
<<Call callbacks at user.tools.callbacks.beforeInstall with the path to the Tool database before installing the Tool. If the callback returns false, don't install the Tool.
<<Call callbacks at user.tools.callbacks.afterInstall with the address of the Tool's database, after installing the Tool. The return value is ignored.
<<10/07/01; 8:32:22 PM by JES
<<Only create the user.tools.databases table for this tool if it's not already defined. Create user.tools.databases.[toolName].flEnabled if not already defined.
<<07/02/01; 2:54:03 AM by JES
<<Install user windowTypes.
<<05/10/01; 4:52:47 PM by JES
<<If this is a Macintosh, make sure that .root files have the correct type/creator codes.
<<04/28/01; 7:44:27 PM by JES
<<Install the website framework site in a try block, because user.webserver.responders.websiteFramework may not exist.
<<12/26/00; 5:39:46 PM by PBS
<<Rebuild the menubar, in case the Tool has a menu referenced in user.menus.
<<11/28/00; 12:30:13 by JES
<<Call playlist.init before installing tools. Call the tool's upgradeToTool script if flUpgradeToTool is true.
<<10/27/00; 2:39:32 PM by JES
<<Make sure the icons folder exists before attempting to write icons to disk.
<<10/18/00; 8:17:36 PM by JES
<<Fixed a bug where a tool's icon files would not be written to disk.
<<10/03/00; 10:33:37 PM by PBS
<<Fix for installing callbacks -- the parameters to table.assign were switched.
<<10/01/00; 1:16:35 AM by PBS
<<Minor cleanups.
<<Tuesday, September 26, 2000 at 4:50:49 PM by JES
<<Created.
bundle { //run beforeInstall callbacks -- if any of the callbacks returns false, don't install the Tool
local (adrcallbacks = @user.tools.callbacks.beforeInstall);
local (adrcallback);
for adrcallback in adrcallbacks {
try {
while typeOf (adrcallback^) == addressType {
adrcallback = adrcallback^};
if not adrcallback^ (f) { //callback returned false -- don't install
return (false)}}}}; //not installed
Frontier.tools.init (); //11/28/00 JES
if not defined ([f]) {
if system.environment.isMac { //05/10/2001 JES: set type/creator
if not (file.type (f) == 'TABL') {
file.setType (f, 'TABL');
file.setCreator (f, 'LAND')}};
fileMenu.open (f, true)};
local (adrTool = @[f]);
local (fname = file.fileFromPath (f));
local (name = Frontier.tools.cleanToolName (fname));
on getTable (itemName, adrAdrTable) {
<<Return true if the table exists in the tool gdb and is non-empty. Return false otherwise. adrAdrTable^ gets the address of the table.
local (adrTable = @adrTool^.[name + itemName]);
if defined (adrTable^) { //does the item exist?
if sizeOf (adrTable^) > 0 { //is the table non-empty?
adrAdrTable^ = adrTable;
return (true)}};
return (false)};
on installItem (adrTable, itemName, flCopy=false) {
<<Install only if the item exists in the tool database.
local (adrItem);
if getTable (itemName, @adrItem) {
if flCopy {
table.assign (@adrTable^.[name], adrItem^)}
else {
table.assign (@adrTable^.[name], adrItem)}}};
installItem (@user.webserver.responders, "Responder", true); //true to make a copy
installItem (@user.betty.rpcHandlers, "RpcHandlers");
installItem (@user.soap.rpcHandlers, "SoapHandlers");
installItem (@user.scheduler.threads, "Thread");
try { //websiteFramework responder might not be installed
installItem (@user.webserver.responders.websiteFramework.data.docTree, "Website")};
bundle { //suite
local (adrSuite);
if getTable ("Suite", @adrSuite) {
bundle { //background
local (backgroundName = name);
local (adrBackground = @adrSuite^.background);
if defined (adrBackground^) {
local (adrscheduler, adrotherscheduler);
bundle { //set adrscheduler, 9/17/10 by DW
if user.tools.prefs.flUseScheduler2 {
adrscheduler = @user.scheduler2;
adrotherscheduler = @user.scheduler}
else {
adrscheduler = @user.scheduler;
adrotherscheduler = @user.scheduler2}};
if defined (adrBackground^.everyMinute) {
adrscheduler^.everyMinute.[name] = @adrBackground^.everyMinute;
if defined (adrotherscheduler^.everyMinute.[name]) {
delete (@adrotherscheduler^.everyMinute.[name])}};
if defined (adrBackground^.everyHour) {
adrscheduler^.hourly.[name] = @adrBackground^.everyHour;
if defined (adrotherscheduler^.hourly.[name]) {
delete (@adrotherscheduler^.hourly.[name])}};
if defined (adrBackground^.everyNight) {
adrscheduler^.overnight.[name] = @adrBackground^.everyNight;
if defined (adrotherscheduler^.overnight.[name]) {
delete (@adrotherscheduler^.overnight.[name])}}}};
bundle { //callbacks
local (adrCallbacks = @adrSuite^.callbacks);
on installCallbacks (adrCallbacks, adrTable) {
if defined (adrCallbacks^) {
local (adr);
for adr in adrTable {
local (callbackName = nameOf (adr^));
if defined (adrCallbacks^.[callbackName]) {
table.assign (@adr^.[name], @adrCallbacks^.[callbackName])}}}};
if defined (adrCallbacks^) {
if system.environment.isPike {
installCallbacks (@adrCallbacks^.fileMenu, @user.tools.commandCallbacks)};
if defined (user.radio.callbacks) {
installCallbacks (@adrCallbacks^.radio, @user.radio.callbacks)};
installCallbacks (@adrCallbacks^.user, @user.callbacks);
installCallbacks (@adrCallbacks^.ftp, @user.html.callbacks.fileWriters.ftp)}};
bundle { //menu
local (adrMenu = @adrSuite^.menu);
if defined (adrMenu^) {
Frontier.tools.installSubMenu (adrMenu)}};
bundle { //localization
local (adrLoc = @adrSuite^.localization);
if defined (adrLoc^) {
on installLocalizations (adrLocalizations, installIn) {
local (adrlang);
for adrlang in adrLocalizations {
local (langName = nameOf (adrlang^));
if not defined (installIn^.[langName]) {
installIn^.[langName] = adrlang}}};
if defined (radio.data.localization.languages) {
if defined (adrLoc^.radio) {
installLocalizations (@adrLoc^.radio, @radio.data.localization.languages)}};
if defined (mainResponder.localization.languages) {
if defined (adrLoc^.mainResponder) {
installLocalizations (@adrLoc^.mainResponder, @mainResponder.localization.languages)}};
if defined (manilaData.localization.languages) {
if defined (adrLoc^.manila) {
installLocalizations (@adrLoc^.manila, @manilaData.localization.languages)}}}}}};
bundle { //nodeTypes
local (appFolder = file.folderFromPath (Frontier.getProgramPath ()));
local (pc = file.getPathChar ());
local (iconsFolder = appFolder + "Appearance" + pc + "Icons" + pc);
local (platform = "windows");
if system.environment.isMac {
platform = "mac"};
on writeIcon (adrIconTable) {
local (adrIcon = @adrIconTable^.[platform]);
if defined (adrIcon^) {
local (iconName = nameOf (parentOf (adrIconTable^)^));
local (fname = iconName);
if system.environment.isWindows {
fname = fname + ".bmp"};
local (f = iconsFolder + fname);
file.sureFilePath (f); //JES 10/27/00: make sure the icons folder exists
if not (file.exists (f)) { //write only if file does not exist
if system.environment.isWindows {
file.writeWholeFile (f, adrIcon^)};
if system.environment.isMac { //write to resource fork
file.writeWholeFile (f, "", 'rsrc', 'RSED'); //type is resource, creator is ResEdit
local (adrResource);
for adrResource in adrIcon { //write each resource
rez.putResource (f, getBinaryType (adrResource^), 128, adrResource)}}}}};
local (adrNodeTypes);
if getTable ("NodeTypes", @adrNodeTypes) {
for adr in adrNodeTypes {
local (adrNodeType = @user.tools.nodeTypes.[nameOf (adr^)]);
try {
adrNodeType^ = adr};
if defined (adr^.icon) {
writeIcon (@adr^.icon)}}}};
bundle { //windowTypes
local (adrWindowTypes);
if getTable ("WindowTypes", @adrWindowTypes) {
for adr in adrWindowTypes {
local (adrWindowType = @user.tools.windowTypes.[nameOf (adr^)]);
try {
adrWindowType^ = adr}}}};
bundle { //set up root updates prefs
local (adrData);
if getTable ("Data", @adrData) {
local (adrVirginPrefs = @adrData^.initialRootUpdatesPrefs);
if defined (adrVirginPrefs^) {
local (tableName = fname);
if string.lower (tableName) endsWith ".root" {
tableName = string.popSuffix (tableName)};
local (adrTable = @user.rootUpdates.servers.[tableName]);
if not defined (adrTable^) {
new (tableType, adrTable)};
if not defined (adrTable^.autobackup) {
adrTable^.autobackup = true};
if not defined (adrTable^.dbName) {
adrTable^.dbName = fname};
if not defined (adrTable^.dialogs) {
adrTable^.dialogs = true};
if not defined (adrTable^.lastUpdate) {
if defined (adrData^.initialRootUpdatesPrefs.lastUpdate) {
adrTable^.lastUpdate = adrVirginPrefs^.lastUpdate}
else {
adrTable^.lastUpdate = date (0)}};
if not defined (adrTable^.method) {
if defined (adrVirginPrefs^.method) {
adrTable^.method = adrVirginPrefs^.method}
else {
adrTable^.method = "mainResponder.subscriptions.update"}};
if not defined (adrTable^.openLog) {
adrTable^.openLog = false};
if not defined (adrTable^.port) {
if defined (adrVirginPrefs^.port) {
adrTable^.port = adrVirginPrefs^.port}
else {
adrTable^.port = 80}};
if not defined (adrTable^.serialNum) {
adrTable^.serialNum = 0};
if not defined (adrTable^.server) {
adrTable^.server = adrVirginPrefs^.server};
if not defined (adrTable^.url) {
if defined (adrVirginPrefs^.url) {
adrTable^.url = adrVirginPrefs^.url}
else {
adrTable^.url = ""}}}}};
bundle { //save the fact that it's an installed tool
local (adrTable = @user.tools.databases.[name]);
if not defined (adrTable^) {
new (tableType, adrTable)};
adrTable^.path = f;
local (now = clock.now ());
adrTable^.lastModified = now;
adrTable^.flInstalled = true;
if not defined (adrtable^.flEnabled) {
adrtable^.flEnabled = true}};
bundle { //store tool info in the temp table
local (adrtempdata = @system.temp.Frontier.tools.[frontier.tools.cleanToolName (name)]);
if not defined (adrtempdata^) {
new (tableType, adrtempdata)};
if not defined (adrtempdata^.lastModified) {
adrtempdata^.lastModified = file.modified (f)};
if defined ([name + "Info"]) {
adrtempdata^.info = [name + "Info"]};
if defined ([name + "Website"]) {
adrtempdata^.url = "/" + name + "/"}};
menus.buildMenuBar (); //PBS 12/26/00: a Tool may have a menu references in user.menus
bundle { //run afterInstall callbacks -- the return value is ignored
local (adrcallbacks = @user.tools.callbacks.afterInstall);
local (adrcallback);
for adrcallback in adrcallbacks {
try {
while typeOf (adrcallback^) == addressType {
adrcallback = adrcallback^};
adrcallback^ (adrTool)}}}; //return value ignored
scheduler.monitorThreads (); //start the Tool's thread immediately
return (true)};
bundle { //debugging
install ("Macintosh HD:Users:davewiner:Desktop:OPML:Guest Databases:apps:Tools:codeLister.root")}
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.