'From Squeak3.4alpha of 6 November 2002 [latest update: #5100] on 11 November 2002 at 2:19:20 am'! "Change Set: squeakMapHooks Date: 11 November 2002 Author: Scott Wallace and Daniel Vainsencher Provides a direct UI to SqueakMap, while still (for the moment anyway) retaining the SqueakMap corpus externally on SqueakMap itself. Incorporates Daniel's design to give the World's open menu a dynamic portion. Scamper, Celeste, and IRC, and SqueakMap now appear in that dynamic portion of the menu; when they are removed from the system, they disappear from the menu; when they return, they reappear in the menu. Participation in the dynamic portion of the open menu requires the implementation of three methods in clients: 1. The GUI class #initialize should call #registerOpenCommand:. 2. The GUI class #unload should call #unregisterOpenCommand:, 3. And it should have some unary message to open the GUI. Provides balloon help for all the items in the open menu, including the dynamic ones. Note: There are three class initialize methods that are modified in this update but which are intentionally *not* invoked at the end of the update."! Object subclass: #TheWorldMenu instanceVariableNames: 'myProject myWorld myHand ' classVariableNames: 'OpenMenuRegistry ' poolDictionaries: '' category: 'Morphic-Kernel'! !Celeste class methodsFor: 'class initialization' stamp: 'sw 11/11/2002 01:56'! initialize "Celeste initialize" "user preferences" CCList _ nil. DeleteInboxAfterFetching _ false. PopServer _ nil. PopUserName _ nil. SmtpServer _ nil. SuppressWorthlessHeaderFields _ true. UserName _ nil. "options with no UI; just set their values directly" FormatWhenFetching _ false. "dictionary of custom filters" CustomFilters _ Dictionary new. MessageCountLimit _ 200. "Add global preferences" Preferences addPreferenceForOptionalCelesteStatusPane. Preferences addPreferenceForCelesteShowingAttachmentsFlag. self registerInOpenMenu ! ! !Celeste class methodsFor: 'class initialization' stamp: 'sw 11/11/2002 01:57'! registerInOpenMenu "Register the receiver in the system's open menu" TheWorldMenu registerOpenCommand: { 'email reader' . { Celeste . #open }. '"Celeste", an e-mail client' } ! ! !Celeste class methodsFor: 'class initialization' stamp: 'sw 11/11/2002 00:04'! unload "Unload the receiver from global registries" TheWorldMenu unregisterOpenCommandWithReceiver: self! ! !IRCConnection class methodsFor: 'class initialization' stamp: 'sw 11/11/2002 01:56'! initialize "IRCConnection initialize" self initializeMessageHandlers. DefaultServer _ 'us.chatnet.org'. DefaultPort _ 6667. DefaultNick _ 'nick'. DefaultUserName _ 'username'. DefaultFullName _ 'J. Doe '. self registerInOpenMenu! ! !IRCConnection class methodsFor: 'class initialization' stamp: 'sw 11/11/2002 01:55'! registerInOpenMenu "Register the receiver in the system's open menu" TheWorldMenu registerOpenCommand: { 'IRC chat' . { IRCConnection . #openConnectionView }. 'Internet Relay Chat' } ! ! !IRCConnection class methodsFor: 'class initialization' stamp: 'sw 11/11/2002 00:02'! unload "Called when the class is being removed" TheWorldMenu unregisterOpenCommandWithReceiver: self! ! !IRCConnection class methodsFor: 'instance creation' stamp: 'sw 11/10/2002 22:40'! openConnectionView "Open an instance of the receiver as a morph" self new openView; openDirectMessagesObserver! ! !Scamper class methodsFor: 'initialization' stamp: 'sw 11/11/2002 01:58'! initialize "Initialize the class" self StartUrl: 'browser:about'. FileList registerFileReader: self. self registerInOpenMenu! ! !Scamper class methodsFor: 'initialization' stamp: 'sw 11/11/2002 01:59'! registerInOpenMenu "Register the receiver in the system's open menu" TheWorldMenu registerOpenCommand: { 'web browser' . { Scamper . #openAsMorph }. '"Scamper", a web browser' }. ! ! !Scamper class methodsFor: 'class initialization' stamp: 'sw 11/11/2002 00:02'! unload "Unload the receiver from global registries" FileList unregisterFileReader: self. TheWorldMenu unregisterOpenCommandWithReceiver: self! ! !TheWorldMenu methodsFor: 'construction' stamp: 'sw 11/11/2002 01:44'! openMenu "Build the open window menu for the world." | menu | menu _ self menu: 'open...'. self fillIn: menu from: { {'browser (b)' . { Browser . #openBrowser}. 'A five-paned tool that lets you see all the code in the system'}. {'package-pane browser' . { PackagePaneBrowser . #openBrowser} . 'Similar to the regular browser, but adds an extra pane at top-left that groups class-categories that start with the same prefix' }. {'workspace (k)' . {self . #openWorkspace}. 'A window for composing text' }. {'file list' . {self . #openFileList} . 'A tool allowing you to browse any file' }. {'file...' . { FileList . #openFileDirectly} . 'Lets you open a window on a single file'}. {'transcript (t)' . {self . #openTranscript}. 'A window used to report messages sent to Transcript' }. "{'inner world' . { WorldWindow . #test1} }." nil. {'method finder' . { self . #openSelectorBrowser} . 'A tool for discovering methods' }. {'message names (W)' . { self . #openMessageNames} . 'A tool for finding and editing methods that contain any given keyword in their names.'}. nil. {'simple change sorter' . {self . #openChangeSorter1} . 'A tool allowing you to view the methods in a single change set' }. {'dual change sorter' . {self . #openChangeSorter2} . 'A tool allowing you to compare and manipulate two change sets concurrently' }. nil. }. self fillIn: menu from: self class registeredOpenCommands, {nil}. self mvcProjectsAllowed ifTrue: [self fillIn: menu from: { {'mvc project' . {self. #openMVCProject} . 'Creates a new project of the classic "mvc" style'} }]. ^ self fillIn: menu from: { {'morphic project' . {self. #openMorphicProject} . 'Creates a new morphic project'}. }.! ! !TheWorldMenu class methodsFor: 'open-menu registry' stamp: 'sw 11/10/2002 23:30'! loadSqueakMap "Load the externally-maintained SqueakMap package if it is not already loaded. Based on code by Gšran Hultgren" | server addr answer | Socket initializeNetwork. server _ #('map1.squeakfoundation.org' 'map2.squeakfoundation.org' 'map.squeak.org' 'map.bluefish.se' 'marvin.bluefish.se:8000') detect: [:srv | addr _ NetNameResolver addressForName: (srv upTo: $:) timeout: 5. addr notNil and: [ answer _ HTTPSocket httpGet: ('http://', srv, '/sm/ping'). answer isString not and: [answer contents = 'pong']]] ifNone: [^ self inform: 'Sorry, no SqueakMap master server responding.']. server ifNotNil: ["Ok, found an SqueakMap server" ChangeSorter newChangesFromStream: ((('http://', server, '/sm/packagebyname/squeakmap/downloadurl') asUrl retrieveContents content) asUrl retrieveContents content unzipped readStream) named: 'SqueakMap']! ! !TheWorldMenu class methodsFor: 'open-menu registry' stamp: 'sw 11/11/2002 00:27'! openPackageLoader "If this method is reached, it means that SMLoader has not yet been loaded; after SqueakMap has come into the image, a different receiver/selector will have been installed under 'Package Loader'; if this method is reached when theoretically SqueakMap is already loaded, presumably this is a grandfathered menu item in a still-up menu, so get the message on to its appropriate recipient." | loaderClass | ((loaderClass _ Smalltalk at: #SMLoader ifAbsent: [nil]) isKindOf: Class) ifTrue: [^ loaderClass open]. (self confirm: 'This requires that you first install "SqueakMap" into your image. SqueakMap is a new architecture for finding, installing, and publishing packages in Squeak. Would you like to install SqueakMap now?' ) ifTrue: [self loadSqueakMap]! ! !TheWorldMenu class methodsFor: 'open-menu registry' stamp: 'sw 11/10/2002 22:56'! registerOpenCommand: anArray "The array received should be of form {'A Label String'. {TargetObject. #command} 'A Help String'} ; the final element is optional but if present will be used to supply balloon help for the menu item in the Open menu. If any previous registration of the same label string is already known, delete the old one." self unregisterOpenCommand: anArray first. OpenMenuRegistry addLast: anArray! ! !TheWorldMenu class methodsFor: 'open-menu registry' stamp: 'sw 11/11/2002 02:11'! registerStandardInternetApps "Register the three currently-built-in internet apps and the hook for SqueakMap with the open-menu registry. This is a one-time initialization affair, contending with the fact that the three apps are already in the image." self registerOpenCommand: { 'Package Loader' . { TheWorldMenu . #openPackageLoader }. 'A tool that lets you browse and load packages from SqueakMap, an index of Squeak code available on the internet' }. #(Scamper Celeste IRCConnection) do: [:sym | (Smalltalk at: sym ifAbsent: [nil]) ifNotNilDo: [:aClass | aClass registerInOpenMenu]] " OpenMenuRegistry _ nil. TheWorldMenu registerStandardInternetApps. "! ! !TheWorldMenu class methodsFor: 'open-menu registry' stamp: 'dvf 5/24/2002 10:38'! registeredOpenCommands "Answer the list of dynamic open commands" OpenMenuRegistry ifNil: [OpenMenuRegistry _ OrderedCollection new]. ^ OpenMenuRegistry! ! !TheWorldMenu class methodsFor: 'open-menu registry' stamp: 'dvf 5/24/2002 10:57'! unregisterOpenCommand: label "Remove the open command with the given label from the registry" self registeredOpenCommands removeAllSuchThat: [:e | e first = label]! ! !TheWorldMenu class methodsFor: 'open-menu registry' stamp: 'sw 11/10/2002 23:58'! unregisterOpenCommandWithReceiver: aReceiver "Remove the open command with the given object as receiver from the registry" self registeredOpenCommands removeAllSuchThat: [:e | e second first == aReceiver]! ! !TheWorldMenu class reorganize! ('open-menu registry' loadSqueakMap openPackageLoader registerOpenCommand: registerStandardInternetApps registeredOpenCommands unregisterOpenCommand: unregisterOpenCommandWithReceiver:) ! "Postscript:" TheWorldMenu registerStandardInternetApps. !