'From etoys3.0 of 24 February 2008 [latest update: #1934] on 25 March 2008 at 6:04:41 pm'! "Change Set: transNebraska-KR Date: 25 March 2008 Author: Korakurider translate several strings in Nebraska"! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:40'! connectButton ^SimpleButtonMorph new label: 'Connect' translated font: Preferences standardButtonFont; color: self buttonColor; target: self; actWhen: #buttonUp; actionSelector: #connect; setBalloonText: 'Press to connect to another audio chat user.' translated ! ! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:41'! messageWaitingAlertIndicator | messageCounter | myalert _ AlertMorph new socketOwner: self. messageCounter _ UpdatingStringMorph on: self selector: #objectsInQueue. messageCounter font: Preferences standardEToysFont. myalert addMorph: messageCounter. messageCounter contents: '0'; color: Color white. messageCounter align: messageCounter center with: myalert center. myalert setBalloonText: 'New messages indicator. This will flash and show the number of messages when there are messages that you haven''t listened to. You can click here to play the next message.' translated. myalert on: #mouseUp send: #playNextMessage to: self. ^myalert! ! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:41'! playButton ^SimpleButtonMorph new label: 'Play' translated font: Preferences standardButtonFont; color: self buttonColor; target: self; actWhen: #buttonUp; actionSelector: #playNextMessage; setBalloonText: 'Play the next new message.' translated ! ! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:42'! recordAndStopButton ^ChatButtonMorph new labelUp: 'Record' translated; labelDown: 'RECORDING' translated; label: 'Record' translated; color: self buttonColor; target: self; actionUpSelector: #stop; actionDownSelector: #record; setBalloonText: 'Press and hold to record a message. It will be sent when you release the mouse.' translated ! ! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:43'! talkBacklogIndicator ^(UpdatingStringMorph on: self selector: #talkBacklog) font: Preferences standardEToysFont; setBalloonText: 'Approximate number of seconds of delay in your messages getting to the other end.' translated! ! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:44'! toggleForHandsFreeTalking ^self simpleToggleButtonFor: self attribute: #handsFreeTalking help: 'Whether you want to talk without holding the mouse down.' translated! ! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:44'! toggleForPlayOnArrival ^self simpleToggleButtonFor: self attribute: #playOnArrival help: 'Whether you want to play messages automatically on arrival.' translated! ! !AudioChatGUI methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:44'! toggleForSendWhileTalking ^self simpleToggleButtonFor: self attribute: #transmitWhileRecording help: 'Whether you want to send messages while recording.' translated! ! !AudioChatGUI methodsFor: 'sending' stamp: 'KR 3/25/2008 17:43'! talkButtonDown EToyListenerMorph confirmListening. self handsFreeTalking ifFalse: [^self record]. theTalkButton label: 'Release' translated. ! ! !AudioChatGUI methodsFor: 'sending' stamp: 'KR 3/25/2008 17:44'! talkButtonUp theTalkButton recolor: self buttonColor. self handsFreeTalking ifFalse: [^self stop]. myrecorder isRecording ifTrue: [ theTalkButton label: 'Talk' translated. ^self stop. ]. self record. theTalkButton label: 'TALKING' translated. ! ! !AudioChatGUI methodsFor: 'stuff' stamp: 'KR 3/25/2008 17:40'! changeTalkButtonLabel | bText | self transmitWhileRecording. handsFreeTalking ifTrue: [theTalkButton labelUp: 'Talk' translated; labelDown: 'Release' translated; label: 'Talk' translated. bText := 'Click once to begin a message. Click again to end the message.' translated] ifFalse: [theTalkButton labelUp: 'Talk' translated; labelDown: (transmitWhileRecording ifTrue: ['TALKING' translated] ifFalse: ['RECORDING' translated]); label: 'Talk' translated. bText := 'Press and hold to record a message.' translated]. bText := transmitWhileRecording ifTrue: [bText , ' The message will be sent while you are speaking.' translated] ifFalse: [bText , ' The message will be sent when you are finished.' translated]. theTalkButton setBalloonText: bText! ! !AudioChatGUI methodsFor: 'stuff' stamp: 'KR 3/25/2008 17:40'! connect | address | mytargetip := FillInTheBlank request: 'Connect to?' translated initialAnswer: (mytargetip ifNil: ['']). mytargetip := (address := NetNameResolver addressForName: mytargetip) ifNil: [''] ifNotNil: [address hostNumber]! ! !ChatNotes methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:37'! openAsMorph | window aColor recordButton stopButton playButton saveButton | window _ (SystemWindow labelled: 'Audio Notes' translated ) model: self. window addMorph: ( (PluggableListMorph on: self list: #notesList selected: #notesListIndex changeSelected: #notesListIndex: menu: #notesMenu: ) autoDeselect: false) frame: (0@0 corner: 0.5@1.0). nameTextMorph _ PluggableTextMorph on: self text: #name accept: nil. nameTextMorph askBeforeDiscardingEdits: false. window addMorph: nameTextMorph frame: (0.5@0 corner: 1.0@0.4). aColor _ Color colorFrom: self defaultBackgroundColor. (recordButton _ PluggableButtonMorph on: self getState: #isRecording action: #record) label: 'record' translated; askBeforeChanging: true; color: aColor; onColor: aColor darker offColor: aColor. window addMorph: recordButton frame: (0.5@0.4 corner: 0.75@0.7). (stopButton _ PluggableButtonMorph on: self getState: #isStopped action: #stop) label: 'stop' translated; askBeforeChanging: true; color: aColor; onColor: aColor darker offColor: aColor. window addMorph: stopButton frame: (0.75@0.4 corner: 1.0@0.7). (playButton _ PluggableButtonMorph on: self getState: #isPlaying action: #play) label: 'play' translated; askBeforeChanging: true; color: aColor; onColor: aColor darker offColor: aColor. window addMorph: playButton frame: (0.5@0.7 corner: 0.75@1.0). (saveButton _ PluggableButtonMorph on: self getState: #isSaving action: #save) label: 'save' translated; askBeforeChanging: true; color: aColor; onColor: aColor darker offColor: aColor. window addMorph: saveButton frame: (0.75@0.7 corner: 1.0@1.0). window openInWorld.! ! !ChatNotes methodsFor: 'morphic' stamp: 'KR 3/25/2008 17:36'! notesMenu: aMenu "Simple menu to delete notes" ^(notesIndex = 0) ifTrue: [aMenu labels: 'update notes' translated lines: #() selections: #(updateNotes)] ifFalse: [aMenu labels: ('delete', String cr, 'update notes' translated) lines: #() selections: #(deleteSelection updateNotes)]! ! !EToyChatMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:46'! rebuild | r1 r2 | r1 _ self addARow: { self simpleToggleButtonFor: self attribute: #acceptOnCR help: 'Send with Return?' translated. self inAColumn: {StringMorph new contents: 'Your message to:' translated; font: Preferences standardMenuFont; lock}. self textEntryFieldNamed: #ipAddress with: '' help: 'IP address for chat partner' translated. }. recipientForm ifNotNil: [ r1 addMorphBack: recipientForm asMorph lock ]. sendingPane _ PluggableTextMorph on: self text: nil accept: #acceptTo:forMorph:. sendingPane hResizing: #spaceFill; vResizing: #spaceFill. sendingPane font: Preferences standardMenuFont. self addMorphBack: sendingPane. r2 _ self addARow: {self inAColumn: {StringMorph new contents: 'Replies'; font: Preferences standardMenuFont; lock}}. receivingPane _ PluggableTextMorph on: self text: nil accept: nil. receivingPane font: Preferences standardMenuFont. receivingPane hResizing: #spaceFill; vResizing: #spaceFill. self addMorphBack: receivingPane. receivingPane spaceFillWeight: 3. {r1. r2} do: [ :each | each vResizing: #shrinkWrap; minHeight: 18; color: Color veryLightGray. ]. sendingPane acceptOnCR: (acceptOnCR ifNil: [acceptOnCR _ true])! ! !EToyChatMorph class methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:45'! chatWindowForIP: ipAddress name: senderName picture: aForm inWorld: aWorld | makeANewOne aSenderBadge existing | existing _ self instanceForIP: ipAddress inWorld: aWorld. existing ifNotNil: [^existing]. makeANewOne _ [ self new recipientForm: aForm; open; setIPAddress: ipAddress ]. EToyCommunicatorMorph playArrivalSound. self doChatsInternalToBadge ifTrue: [ aSenderBadge _ EToySenderMorph instanceForIP: ipAddress inWorld: aWorld. aSenderBadge ifNotNil: [ aSenderBadge startChat: false. ^aSenderBadge findDeepSubmorphThat: [ :x | x isKindOf: EToyChatMorph] ifAbsent: makeANewOne ]. aSenderBadge _ EToySenderMorph instanceForIP: ipAddress. aSenderBadge ifNotNil: [ aSenderBadge _ aSenderBadge veryDeepCopy. aSenderBadge killExistingChat; openInWorld: aWorld; startChat: false. ^aSenderBadge findDeepSubmorphThat: [ :x | x isKindOf: EToyChatMorph] ifAbsent: makeANewOne ]. (aSenderBadge _ EToySenderMorph new) userName: senderName userPicture: aForm userEmail: 'unknown' translated userIPAddress: ipAddress; position: 200@200; openInWorld: aWorld; startChat: false. ^aSenderBadge findDeepSubmorphThat: [ :x | x isKindOf: EToyChatMorph] ifAbsent: makeANewOne ]. ^makeANewOne value. ! ! !EToyFridgeMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:48'! groupToggleButton ^(self inAColumn: { (EtoyUpdatingThreePhaseButtonMorph checkBox) target: self; actionSelector: #toggleChoice:; arguments: {'group'}; getSelector: #getChoice:; setBalloonText: 'Changes between group mode and individuals' translated; step }) hResizing: #shrinkWrap ! ! !EToyFridgeMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:48'! rebuild | row filler fudge people maxPerRow insetY | updateCounter _ self class updateCounter. self removeAllMorphs. (self addARow: { filler _ Morph new color: Color transparent; extent: 4@4. }) vResizing: #shrinkWrap. self addARow: { (StringMorph contents: 'the Fridge' translated) lock. self groupToggleButton. }. row _ self addARow: {}. people _ self class fridgeRecipients. maxPerRow _ people size < 7 ifTrue: [2] ifFalse: [3]. "how big can this get before we need a different approach?" people do: [ :each | row submorphCount >= maxPerRow ifTrue: [row _ self addARow: {}]. row addMorphBack: ( groupMode ifTrue: [ (each userPicture scaledToSize: 35@35) asMorph lock ] ifFalse: [ each veryDeepCopy killExistingChat ] ) ]. fullBounds _ nil. self fullBounds. "htsBefore _ submorphs collect: [ :each | each height]." fudge _ 20. insetY _ self layoutInset. insetY isPoint ifTrue: [insetY _ insetY y]. filler extent: 4 @ (self height - filler height * 0.37 - insetY - borderWidth - fudge) truncated. "self fixLayout. htsAfter _ submorphs collect: [ :each | each height]. {htsBefore. htsAfter} explore." ! ! !EToyIncomingMessage class methodsFor: 'handlers' stamp: 'KR 3/25/2008 18:00'! handleNewSeeDesktopFrom: dataStream sentBy: senderName ipAddress: ipAddressString "more later" ^ EToyChatMorph chatFrom: ipAddressString name: senderName text: ipAddressString,' would like to see your desktop' translated. ! ! !EToyIncomingMessage class methodsFor: 'handlers' stamp: 'KR 3/25/2008 18:01'! handleNewStatusRequestFrom: dataStream sentBy: senderName ipAddress: ipAddressString "more later" ^ EToyChatMorph chatFrom: ipAddressString name: senderName text: ipAddressString,' would like to know if you are available' translated. ! ! !EToyListenerMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:50'! mouseDownEvent: event for: aMorph | menu selection depictedObject | depictedObject := aMorph firstSubmorph valueOfProperty: #depictedObject. menu := CustomMenu new. menu add: 'Grab' translated action: [event hand attachMorph: depictedObject veryDeepCopy]; add: 'Delete' translated action: [self class removeFromGlobalIncomingQueue: depictedObject. self rebuild]. selection := menu build startUpCenteredWithCaption: 'Morph from ' translated , (aMorph submorphs second) firstSubmorph contents. selection ifNil: [^self]. selection value! ! !EToyListenerMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:51'! rebuild | earMorph | updateCounter _ UpdateCounter. self removeAllMorphs. self addGateKeeperMorphs. GlobalListener ifNil: [ earMorph _ (self class makeListeningToggleNew: false) asMorph. earMorph setBalloonText: 'Click to START listening for messages' translated. earMorph on: #mouseUp send: #startListening to: self. ] ifNotNil: [ earMorph _ (self class makeListeningToggleNew: true) asMorph. earMorph setBalloonText: 'Click to STOP listening for messages' translated. earMorph on: #mouseUp send: #stopListening to: self. ]. self addARow: {self inAColumn: {earMorph}}. self addARow: { self inAColumn: {(StringMorph contents: 'Incoming communications' translated ) lock}. self indicatorFieldNamed: #working color: Color blue help: 'working' translated. self indicatorFieldNamed: #communicating color: Color green help: 'receiving' translated. }. "{thumbForm. newObject. senderName. ipAddressString}" self class globalIncomingQueueCopy do: [ :each | self addNewObject: each second thumbForm: each first sentBy: each third ipAddress: each fourth. ].! ! !EToyListenerMorph class methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:49'! confirmListening self isListening ifFalse: [ (self confirm: 'You currently are not listening and will not hear a reply. Shall I start listening for you?' translated) ifTrue: [ self startListening ]. ]. ! ! !EToyMorphsWelcomeMorph methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:51'! initialize "initialize the state of the receiver" | earMorph | super initialize. "" self layoutInset: 8 @ 8. "earMorph _ (EToyListenerMorph makeListeningToggle: true) asMorph." earMorph _ TextMorph new contents: 'Morphs welcome here'; fontName: Preferences standardEToysFont familyName size: 18; centered; lock. self addARow: {earMorph}. self setBalloonText: 'My presence in this world means received morphs may appear automatically' translated! ! !EToyMultiChatMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:54'! editEvent: anEvent for: aMorph | answer initialText aFillInTheBlankMorph | (aMorph bounds containsPoint: anEvent cursorPoint) ifFalse: [^self]. initialText _ String streamContents: [ :strm | targetIPAddresses do: [ :each | strm nextPutAll: each; cr]. ]. aFillInTheBlankMorph _ FillInTheBlankMorph new setQuery: 'Who are you chatting with?' translated initialAnswer: initialText answerHeight: 250 acceptOnCR: false. aFillInTheBlankMorph responseUponCancel: nil. self world addMorph: aFillInTheBlankMorph centeredNear: anEvent cursorPoint. answer _ aFillInTheBlankMorph getUserResponse. answer ifNil: [^self]. self updateIPAddressField: (answer findTokens: ' ',String cr). ! ! !EToyMultiChatMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:54'! rebuild | r1 r2 | r1 _ self addARow: { self simpleToggleButtonFor: self attribute: #acceptOnCR help: 'Send with Return?' translated. self inAColumn: {StringMorph new contents: 'Multi chat with:' translated; lock}. self textEntryFieldNamed: #ipAddress with: '' help: 'Click to edit participant list' translated. }. sendingPane _ PluggableTextMorph on: self text: nil accept: #acceptTo:forMorph:. sendingPane hResizing: #spaceFill; vResizing: #spaceFill. self addMorphBack: sendingPane. r2 _ self addARow: {self inAColumn: {StringMorph new contents: 'Replies' translated; lock}}. receivingPane _ PluggableTextMorph on: self text: nil accept: nil. receivingPane hResizing: #spaceFill; vResizing: #spaceFill. self addMorphBack: receivingPane. receivingPane spaceFillWeight: 3. {r1. r2} do: [ :each | each vResizing: #shrinkWrap; minHeight: 18; color: Color veryLightGray. ]. self updateIPAddressField: targetIPAddresses. sendingPane acceptOnCR: (acceptOnCR ifNil: [acceptOnCR _ true]).! ! !EToySenderMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:56'! checkOnAFriend | gateKeeperEntry caption choices resp | gateKeeperEntry _ EToyGateKeeperMorph entryForIPAddress: self ipAddress. caption _ 'Last name: ' translated ,gateKeeperEntry latestUserName, '\Last message in: ' translated ,gateKeeperEntry lastIncomingMessageTimeString, '\Last status check at: ' translated ,gateKeeperEntry lastTimeCheckedString, '\Last status in: ' translated ,gateKeeperEntry statusReplyReceivedString. choices _ 'Get his status now\Send my status now' translated. resp _ (PopUpMenu labels: choices withCRs) startUpWithCaption: caption withCRs. resp = 1 ifTrue: [ gateKeeperEntry lastTimeChecked: Time totalSeconds. self sendStatusCheck. ]. resp = 2 ifTrue: [ self sendStatusReply. ]. ! ! !EToySenderMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:57'! startNebraskaClient | newMorph | [ [ newMorph _ NetworkTerminalMorph connectTo: self ipAddress. WorldState addDeferredUIMessage: [newMorph openInStyle: #scaled] fixTemps. ] on: Error do: [ :ex | WorldState addDeferredUIMessage: [ self inform: 'No connection to: ' translated. self ipAddress,' (',ex printString,')' ] fixTemps ]. ] fork ! ! !EToySenderMorph methodsFor: 'as yet unclassified' stamp: 'KR 3/25/2008 17:58'! userName: aString userPicture: aFormOrNil userEmail: emailString userIPAddress: ipString | dropZoneRow | self setProperty: #currentBadgeVersion toValue: self currentBadgeVersion. userPicture _ aFormOrNil ifNil: [ (TextStyle default fontOfSize: 26) emphasized: 1; characterFormAt: $? ]. userPicture _ userPicture scaledToSize: 61@53. self killExistingChat. self removeAllMorphs. self useRoundedCorners. self addARow: { self inAColumn: {(StringMorph contents: aString) lock} }. dropZoneRow _ self addARow: { self inAColumn: {userPicture asMorph lock} }. self establishDropZone: dropZoneRow. self addARow: { self textEntryFieldNamed: #emailAddress with: emailString help: 'Email address for this person' }; addARow: { self textEntryFieldNamed: #ipAddress with: ipString help: 'IP address for this person' }; addARow: { self indicatorFieldNamed: #working color: Color blue help: 'working' translated. self indicatorFieldNamed: #communicating color: Color green help: 'sending' translated. self buttonNamed: 'C' action: #startChat color: Color paleBlue help: 'Open a written chat with this person' translated. self buttonNamed: 'T' action: #startTelemorphic color: Color paleYellow help: 'Start telemorphic with this person' translated. self buttonNamed: '!!' action: #tellAFriend color: Color paleGreen help: 'Tell this person about the current project' translated. self buttonNamed: '?' action: #checkOnAFriend color: Color lightBrown help: 'See if this person is available' translated. self buttonNamed: 'A' action: #startAudioChat color: Color yellow help: 'Open an audio chat with this person' translated. self buttonNamed: 'S' action: #startNebraskaClient color: Color white help: 'See this person''s world (if he allows that)' translated. }. ! ! !NebraskaServerMorph methodsFor: 'drawing' stamp: 'KR 3/25/2008 17:28'! updateCurrentStatusString self server ifNil:[ currentStatusString _ '' translated. currentBacklogString _ ''. ] ifNotNil:[ currentStatusString _ ' Nebraska: {1} clients' translated format: {self server numClients printString}. currentBacklogString _ 'backlog: ' translated, ((previousBacklog _ self server backlog) // 1024) printString,'k' ]. ! ! !NebraskaServerMorph methodsFor: 'initialization' stamp: 'KR 3/25/2008 17:23'! rebuild | myServer toggle closeBox font | font _ StrikeFont familyName: #Palatino size: 14. self removeAllMorphs. self setColorsAndBorder. self updateCurrentStatusString. toggle _ SimpleHierarchicalListMorph new perform: ( fullDisplay ifTrue: [#expandedForm] ifFalse: [#notExpandedForm] ). closeBox _ SimpleButtonMorph new borderWidth: 0; label: 'X' font: Preferences standardEToysButtonFont; color: Color transparent; actionSelector: #delete; target: self; extent: 14@14; setBalloonText: 'End Nebrasks session' translated. self addARow: { self inAColumn: {closeBox}. self inAColumn: { UpdatingStringMorph new useStringFormat; target: self; font: font; getSelector: #currentStatusString; contents: self currentStatusString; stepTime: 2000; lock. }. self inAColumn: { toggle asMorph on: #mouseUp send: #toggleFull to: self; setBalloonText: 'Show more or less of Nebraska Status' translated }. }. myServer _ self server. (myServer isNil or: [fullDisplay not]) ifTrue: [ ^World startSteppingSubmorphsOf: self ]. "--- the expanded display ---" self addARow: { self inAColumn: { UpdatingStringMorph new useStringFormat; target: self; font: font; getSelector: #currentBacklogString; contents: self currentBacklogString; stepTime: 2000; lock. }. }. self addARow: { self inAColumn: { (StringMorph contents: '--clients--' translated) lock; font: font. }. }. myServer clients do: [ :each | self addARow: { UpdatingStringMorph new useStringFormat; target: each; font: font; getSelector: #currentStatusString; contents: each currentStatusString; stepTime: 2000; lock. } ]. World startSteppingSubmorphsOf: self.! ! !NebraskaServerMorph methodsFor: 'submorphs-add/remove' stamp: 'KR 3/25/2008 17:24'! delete self server ifNotNil:[ (self confirm:'Shutdown the server?' translated) ifTrue:[self world remoteServer: nil]]. super delete.! ! !NetworkTerminalMorph class methodsFor: 'instance creation' stamp: 'KR 3/25/2008 17:31'! socketConnectedTo: serverHost port: serverPort | sock | Socket initializeNetwork. sock _ Socket new. [sock connectTo: (NetNameResolver addressForName: serverHost) port: serverPort] on: ConnectionTimedOut do: [:ex | self error: 'could not connect to server' translated ]. ^StringSocket on: sock ! !