Monday, November 08, 2010 at 12:03 AM.
system.verbs.builtins.Frontier.tools.windowTypes.commands.save
on save (adrItem=nil, flClosing=false) {
<<Handle the Save command.
<<Changes:
<<02/05/00; 5:29:12 PM by PBS
<<Build the table of information about this window, so we can preserve size, position, scroll state, and expansion state.
<<03/23/00; 12:15:17 PM by PBS
<<Use the About Window for feedback when saving.
<<03/24/00; 11:14:47 AM by PBS
<<Don't update the last saved date after a failed save. Display a friendly error message explaining that there was a communication error -- display the title of the object and the name of the server.
<<03/24/00; 6:41:08 PM by PBS
<<Convert cascadingStyleSheet to css -- because manila.css is the name of the handler. This fixes saving CSS items back to the server.
<<Fri, Jul 7, 2000 at 11:00:09 PM by AR
<<Call any scripts in user.pike.commandCallbacks.save
<<If one of the scripts returns true, we're done
<<07/23/00; 7:59:16 PM by PBS
<<If it's a local outline document, save it to disk at the right location.
<<08/16/00; 10:38:06 PM by JES
<<Always bring the last frontmost window to the front after saving.
<<Monday, August 21, 2000 at 5:48:56 AM by DW
<<Provide feedback when saving local files.
<<08/22/00; 9:59:29 PM by PBS
<<When saving a message, don't promote it to a story if storyInfo.flAddToStoriesList exists and is false. This preserves backwards compatibility, but it also provides a way for people to create and reply to dg messages without making them stories.
<<08/23/00; 3:14:32 AM by PBS
<<Support custom serialization routines for advanced items. This allows the plain XML display to be over-ridden.
<<Sat, Aug 26, 2000 at 6:13:44 PM by JES
<<Save weblog pages by rendering with the website framework, according to their #ftpSite table settings.
<<09/15/00; 1:55:51 PM by PBS
<<If the outline is raw XML, don't try to save it as an outlineDocument.
<<09/16/00; 5:22:22 PM by PBS
<<.opml is the default extension when saving new files.
<<09/16/00; 3:16:02 PM by PBS
<<Save file system objects -- classic text files -- okay.
<<09/21/00; 5:35:57 PM by PBS
<<When saving an OPML file, save with Radio UserLand's file creator code and OPML file type.
<<09/22/00; 5:00:21 PM by PBS
<<Before saving to a Manila server, check the offline status.
<<10/03/00; 6:41:58 PM by PBS
<<Callbacks can be addresses.
<<10/07/00; 1:37:06 PM by PBS
<<If there's an error saving, report the actual error to the user.
<<11/03/00; 1:13:17 AM by JES
<<Handle saving the message as opml if the server is compatible.
<<11/20/00; 3:39:43 PM by JES
<<Call the user callbacks when saving local outlines or rendering wsf pages.
<<11/20/00; 10:19:36 PM by JES
<<Allow callbacks to consume the save action for weblog pages and local outlines.
<<11/21/00; 1:22:36 AM by PBS
<<Use generic template save routine when the template doesn't have a dedicated handler.
<<11/29/00; 10:34:08 PM by JES
<<Dereference callback addresses in a try block in case a tool's odb is not opened
<<12/20/00; 1:19:14 AM by JES
<<Bug fix: View in Browser works for new stories and new messages.
<<12/21/00; 11:07:10 AM by PBS
<<Bring the window being saved back to front only if the About window is frontmost. Fixes bug reported on Scripting News: http://scriptingnews.userland.com/backissues/2000/12/21
<<12/26/00; 3:04:22 PM by PBS
<<When doing a save as plain text, allow the user to decide the extension, don't force an .xml or whatever extension. If no extension is provided, then use .txt.
<<12/31/00; 12:33:46 AM by JES
<<On Macs, convert opml text to latin text before saving local outlines to disk.
<<01/24/01; 1:46:18 PM by JES
<<If an opml file contained any xml headers like xml-stylesheet declarations, include them when saving the file.
<<02/08/01; 4:05:36 PM by JES
<<Bug fix: If the About Window is frontmost, save Radio.root.
<<02/21/01; 2:16:27 AM by JES
<<Save the file using the recorded line-ending format. Preserve Mac type/creator codes.
<<3/16/01; 10:30:51 PM by PBS
<<If the About window is already open, don't call window.about (), as that messes up window cascade order.
if adrItem == nil { //default to frontmost window
adrItem = window.frontmost ()};
on saveDatabase () {
msg ("Saving database...");
if typeOf (adrItem) == addressType {
fileMenu.saveMyRoot (adritem)}
else {
fileMenu.save ()};
msg ("")}; //clear the feedback message
if not defined (adrItem^) { //save Radio.root
adrItem = @root;
saveDatabase ();
return (true)};
on runCallbacks (adrCallback) { //call callbacks
if defined (adrCallback^) {
local (flConsumed = false);
local (adrScript);
for adrScript in adrCallback {
try { //11/30/00 JES
while typeOf (adrScript^) == addressType { //follow addresses
adrScript = adrScript^};
flConsumed = adrScript^ (adrItem, flClosing)};
if flConsumed {
return (true)}}};
return (false)};
if runCallbacks (@user.tools.commandCallbacks.save) {
return (true)};
if system.environment.isRadio {
if defined (user.pike.commandCallbacks) {
if runCallbacks (@user.pike.commandCallbacks.save) {
return (true)}}};
bundle { //look for a windowType that handles this command
local (type, adrType);
if window.attributes.getOne ("type", @type, adrItem) {
if Frontier.tools.windowTypes.findWindowType (type, @adrType, adrItem) {
if defined (adrType^.save) {
if adrType^.save (adrItem, flClosing) {
window.attributes.setOne ("lastSaved", timeModified (adrItem), adrItem);
saveDatabase ();
return (true)}
else {
return (false)}}}}};
saveDatabase ();
return (true)};
<<bundle //old code
<<if adrItem == nil //get the current selection
<<try {adrItem = table.getCursorAddress ()}
<<local (frontWindow = window.frontMost ())
<<local (aboutWindowName = "About Radio UserLand")
<<
<<on saveDatabase () // 8/26/00 JES: factored saving code
<<msg ("Saving database...")
<<if typeOf (adrItem) == addressType
<<fileMenu.saveMyRoot (adritem)
<<else
<<fileMenu.save ()
<<
<<if window.frontMost () == aboutWindowName //PBS 12/21/00: bring editing window back to front only if the About window is frontmost
<<try {edit (frontWindow)} //JES 08/16/00
<<
<<msg ("") //clear the feedback message
<<
<<local (flConsumed = false)
<<if adrItem != nil //11/20/00 JES: call the user callbacks
<<if defined (user.pike.commandCallbacks.save)
<<local (adrcallback)
<<for adrcallback in @user.pike.commandCallbacks.save
<<try //11/30/00 JES
<<while typeOf (adrcallback^) == addressType //follow addresses
<<adrcallback = adrcallback^
<<flConsumed = adrcallback^ (adrItem, flClosing)
<<if flConsumed
<<break
<<
<<if not defined (adrItem^) //save Radio.root
<<adrItem = @root
<<saveDatabase ()
<<return (true)
<<
<<if not flConsumed //JES 08/26/00: handle rendering website framework pages
<<if defined (suites.playlist.weblog.utilities.windowIsWebPage) and suites.playlist.weblog.utilities.windowIsWebPage (adrItem)
<<html.buildOnePage (adrItem)
<<
<<saveDatabase ()
<<
<<if not flConsumed //PBS 07/23/00: handle local outline documents
<<if pike.isLocalOutline (adrItem) //handle local outlines only in this block
<<local (adrTable = parentOf (adrItem^))
<<local (f)
<<on saveFile ()
<<msg ("Saving \"" + f + "\".") //Monday, August 21, 2000 at 5:47:45 AM by DW
<<adrTable^.title = file.fileFromPath (f)
<<window.setTitle (adrItem, adrTable^.title)
<<local (xmlText)
<<if defined (adrTable^.flOutlineDocument) //PBS 09/15/00: it may be raw XML
<<if not (adrTable^.flOutlineDocument)
<<xmlText = string (adrItem^) //raw XML is just string of the outline
<<bundle //add linefeeds if this is Windows
<<if system.environment.isWindows
<<xmlText = string.replaceAll (xmlText, "\r", "\r\n")
<<if defined (adrTable^.fileCreator) //02/21/2001 JES: save with recorded type/creator
<<file.writeWholeFile (f, xmlText, adrTable^.fileType, adrTable^.fileCreator)
<<else
<<file.writeWholeFile (f, xmlText, 'TEXT', 'Radu')
<<if xmlText == nil //if it's an outlineDocument, xmlText is not yet set
<<xmlText = op.outlineToXml (adrItem) //convert to outlineDocument
<<if defined (adrTable^.lineEnding) //02/21/2001 JES: save the file with the recorded line-endings
<<xmlText = string.replaceAll (xmlText, "\r", adrTable^.lineEnding)
<<bundle //01/23/01 JES: support style sheet declarations
<<if defined (adrTable^.xmlHeaders)
<<local (ix = string.patternMatch ("?>", xmlText) + 3)
<<xmlText = string.insert (adrTable^.xmlHeaders, xmlText, ix)
<<if system.environment.isMac //12/31/00 JES: convert Mac text to latin
<<xmlText = latinToMac.macToLatin (xmlText)
<<if defined (adrTable^.fileCreator) //02/21/2001 JES: save with recorded type/creator
<<file.writeWholeFile (f, xmlText, adrTable^.fileType, adrTable^.fileCreator)
<<else
<<file.writeWholeFile (f, xmlText, 'OPML', 'Radu') //PBS 09/21/00: save with Mac codes
<<adrTable^.f = f
<<adrTable^.lastSaved = clock.now ()
<<msg ("")
<<return (true)
<<if defined (adrTable^.f)
<<f = adrTable^.f
<<saveFile ()
<<else
<<if not (file.putFileDialog ("Save as:", @f))
<<return (false)
<<local (defaultExtension = ".opml")
<<local (flOutlineDocument = false)
<<if defined (adrTable^.flOutlineDocument) //PBS 12/26/00: check extension only with OPML documents
<<if adrTable^.flOutlineDocument
<<flOutlineDocument = true
<<
<<if flOutlineDocument //ensure .opml extension
<<if not (string.lower (f) endsWith defaultExtension)
<<f = f + defaultExtension
<<else //PBS 12/26/00: if no extension, use .txt extension
<<local (fname = file.fileFromPath (f))
<<if not (fname contains ".")
<<f = f + ".txt"
<<
<<saveFile ()
<<
<<return (true)
<<
<<bundle //PBS 09/18/00: handle saving the home page of the server
<<local (adrHomePage = @system.temp.playlist.serverHomePage)
<<if defined (adrHomePage^)
<<if adrItem == adrHomePage
<<local (s = string (adrHomePage^)) //get the text
<<local (f = user.playlist.prefs.wwwFolder + "index.html")
<<file.writeWholeFile (f, s, 'TEXT', user.html.prefs.textFileCreator, clock.now ())
<<return (true)
<<
<<local (flAboutWindowOpen = window.isOpen (aboutWindowName))
<<
<<on savingError (displayTitle)
<<Handle errors in saving the document. Display a message and clean up.
<<fileMenu.save ()
<<msg ("")
<<PBS 04/03/00: save the actual tryError
<<if not defined (temp.pike)
<<new (tableType, @temp.pike)
<<wp.newTextObject (tryError, @temp.pike.lastSaveError)
<<if not flAboutWindowOpen //close the About Window if it wasn't open before doing a save
<<window.close (aboutWindowName)
<<local (hostName = pike.getServerHostName (adrItem))
<<scriptError ("Can't save " + displayTitle + " because of an error communicating with the server, " + hostName + ".")
<<scriptError ("Can't save " + displayTitle + " because " + tryError + ".")
<<
<<if adrItem!= nil
<<bundle //PBS 03/23/00: display feedback message
<<if not flAboutWindowOpen //PBS 03/16/01: this call messes up window cascade order if the About window was already open
<<window.about ()
<<
<<if not flConsumed
<<local (windowType = pike.getWindowType (adrItem))
<<if windowType != ""
<<
<<if not (playlist.tcpOkay ()) //PBS 09/22/00: check offline status
<<return (false)
<<
<<local (adrTable = parentOf (adrItem^))
<<
<<local (bodyType = "text/x-outline-tabbed")
<<
<<local (windowInfoTable = pike.buildWindowInfoTable (adrItem)) //PBS 02/05/00: get the window info table
<<
<<local (flServerAcceptsOpml = false)
<<if defined (adrTable^.siteInfo.flAcceptsOpml) //11/03/00 JES
<<flServerAcceptsOpml = adrTable^.siteInfo.flAcceptsOpml
<<case windowType
<<"advancedItems"
<<local (itemTypeName = nameOf (adrTable^))
<<msg ("Saving " + itemTypeName + "...")
<<local (handlerName = pike.advancedItemToHandlerName (itemTypeName))
<<try
<<local (s = string (adrItem^))
<<if defined (adrTable^.itemInfo.adrSerializeRoutine) //PBS 08/23/00: call serialization routine if there is one
<<if defined (adrTable^.itemInfo.adrSerializeRoutine^)
<<s = adrTable^.itemInfo.adrSerializeRoutine^ (adrTable)
<<if defined (manila.[handlerName].set)
<<manila.[handlerName].set (@adrTable^.siteinfo, s, windowInfoTable)
<<else //PBS 11/20/00: use generic save routine
<<manila.advancedPref.set (@adrTable^.siteInfo, itemTypeName, s, windowInfoTable)
<<else
<<savingError ("the " + itemTypeName)
<<adrTable^.lastSaved = clock.now ()
<<"savedStories"
<<if flServerAcceptsOpml
<<bodyType = "text/x-opml"
<<local (subject = adrTable^.storyinfo.subject)
<<msg ("Saving \"" + subject + "\"...")
<<local (adrStory = @adrTable^.storyinfo)
<<try
<<if flServerAcceptsOpml //11/03/00 JES
<<local (opmlText = op.outlineToXml (adrItem, ownerEmail:adrTable^.siteInfo.username))
<<manila.message.set (@adrTable^.siteinfo, adrStory^.msgnum, adrStory^.subject, opmlText, bodyType, windowInfoTable) //PBS 02/05/00: added windowInfoTable parameter
<<else
<<manila.message.set (@adrTable^.siteinfo, adrStory^.msgnum, adrStory^.subject, string (adrItem^), bodyType, windowInfoTable) //PBS 02/05/00: added windowInfoTable parameter
<<else
<<temp.errorText = tryError
<<savingError ("\"" + subject + "\"")
<<adrTable^.lastSaved = clock.now ()
<<"newStories"
<<if flServerAcceptsOpml
<<bodyType = "text/x-opml"
<<local (subject = adrTable^.storyinfo.subject)
<<msg ("Saving \"" + subject + "\"...")
<<
<<local (resulttable)
<<try
<<local (inResponseTo = 0)
<<if defined (adrTable^.storyInfo.inResponseTo)
<<inResponseTo = adrTable^.storyInfo.inResponseTo
<<if flServerAcceptsOpml //11/03/00 JES
<<local (opmlText = op.outlineToXml (adrItem, ownerEmail:adrTable^.siteInfo.username))
<<resulttable = manila.message.create (@adrTable^.siteinfo, subject, opmlText, bodyType, inResponseTo, windowInfoTable)
<<else
<<resulttable = manila.message.create (@adrTable^.siteinfo, subject, string (adrItem^), bodyType, inResponseTo, windowInfoTable)
<<else
<<temp.errorText = tryError
<<savingError ("\"" + subject + "\"")
<<
<<if not flClosing //copy to savedStories
<<local (adrStoryTable = pike.getStoryTableAddress (@adrTable^.siteinfo, resulttable.msgnum))
<<adrStoryTable^.siteinfo = adrTable^.siteinfo
<<adrStoryTable^.storyinfo = resulttable
<<
<<table.move (adrItem, adrStoryTable)
<<pike.setWindowTitle (adrStoryTable)
<<
<<adrTable^.storyinfo.url = adrStoryTable^.storyinfo.url //12/20/00 JES: make view in browser work for new stories
<<
<<adrStoryTable^.lastSaved = clock.now ()
<<
<<local (flAddToStoriesList = true) //PBS 08/22/00: if flAddToStoriesList exists and is false, don't add to stories. This way we can have messages that aren't stories.
<<if defined (adrTable^.storyInfo.flAddToStoriesList)
<<if not (adrTable^.storyInfo.flAddToStoriesList)
<<flAddToStoriesList = false
<<if flAddToStoriesList
<<manila.message.addToStoriesList (@adrTable^.siteinfo, resulttable.msgnum)
<<
<<if window.isOpen (adrItem)
<<edit (adrItem) //PBS 03/24/00: bring it back to the front, in case the About Window came to the front
<<
<<saveDatabase ()
<<bundle // factored code
<<msg ("Saving database...")
<<if typeOf (adrItem) == addressType
<<fileMenu.saveMyRoot (adritem)
<<else
<<fileMenu.save ()
<<
<<try {edit (frontWindow)} //JES 08/16/00
<<
<<msg ("") //clear the feedback message
<<if not flAboutWindowOpen //close the About Window if it wasn't open before doing a save
<<window.close (aboutWindowName)
<<
<<return (true)
bundle { // debugging
save (window.frontMost ())}
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.