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.