David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk:
http://source.squeak.org/trunk/MonticelloConfigurations-dtl.158.mcz
==================== Summary ====================
Name: MonticelloConfigurations-dtl.158
Author: dtl
Time: 15 February 2020, 7:21:06.721682 pm
UUID: df6a3d9c-f241-451b-a4f7-5b441e0bf29b
Ancestors: MonticelloConfigurations-dtl.157
Allow an MCMcmUpdater to bypass UI updates when not interactive. Force transcript to open, and present concluding OK dialog, only if interactive.
=============== Diff against MonticelloConfigurations-mt.156 ===============
Item was changed:
Object subclass: #MCMcmUpdater
instanceVariableNames: 'repository updateMapName lastUpdateMap'
+ classVariableNames: 'DefaultUpdateMap DefaultUpdateURL Registry SkipPackages UpdateFromServerAtStartup UpdateMissingPackages'
- classVariableNames: 'DefaultUpdateMap DefaultUpdateURL Registry SkipPackages UpdateFromServerAtStartup UpdateMissingPackages Updaters'
poolDictionaries: ''
category: 'MonticelloConfigurations'!
!MCMcmUpdater commentStamp: 'dtl 10/12/2015 19:45' prior: 0!
MCMcmUpdater provides utility methods for updating Monticello packages from Monticello configurations.
When Monticello configurations are stored in a repository (or repositories), MCMcmUpdater acts as an update stream. It first ensures that each configuration map has been loaded in sequence, then updates the last configuration map to the most recent version for each specified package, and finally loads these versions to produce a fully updated configuration.
Currently if a set of packages are unloaded from the image, using this class to reload them may cause problems, depending on what dependencies those classes have. Success is not assured. Removing packages via SmalltalkImage>>unloadAllKnownPackages will be successful, it flags the packages removed so that they are not loaded by this utility.
If you wish to not have MCMcmUpdater update packages, there are two ways to handle this:
1) To have MCMcmUpdater not update any packages not currently in the image set the UpdateMissingPackages preference to false:
MCMcmUpdater updateMissingPackages: false
Note that any new packages added to the repositories will not be picked up when this is turned off.
2) To have MCMcmUpdater not update a specific package, evaluate
MCMcmUpdater disableUpdatesOfPackage: <packageName>
Class Variables definitions:
DefaultUpdateURL - String: the URL that will be checked by default for updates. This would be set for a common standard location to check.
Repository - A registry of known MCMcmUpdater instances identified by repository URL and update map name.
SkipPackages - Set of Strings: names of packages to not update in MCMcmUpdater (empty by default).
UpdateMissingPackages - Boolean: if true (default), new packages in the update config map will be loaded unless they are in SkipPackages. If false, packages not currently loaded in the image will not be loaded by MCMcmUpdater. (This can be dangerous if packages are split - use at your own risk).
Instance Variables:
updateMapName - Base name of the files used for this updater, typically a name such as 'update' or 'update.spur'.
repository - URL of the repository in which the update maps are located.
lastUpdateMap - Dictionary of Integer: version number of the last loaded update map per repository. Keeps track of the last configuration map, so that the utility will not have to run through the full history in the repositories each time you ask to update.
!
Item was changed:
----- Method: MCMcmUpdater class>>initialize (in category 'class initialization') -----
initialize
"MCMcmUpdater initialize"
- self flag: #TODO. "remove Updaters class var after transition to Registry"
-
DefaultUpdateURL ifNil:[
DefaultUpdateURL := MCHttpRepository trunkUrlString.
DefaultUpdateMap := self defaultBaseName.
].
-
- Registry ifNil: [ "Migrate from Updaters class var to Registry"
- "Set new repository ivar in all existing instances"
- Updaters keysAndValuesDo: [ :k :v | v repository: k].
- "Populate the new registry"
- Updaters do: [:e | e register].
- "Set the default update map name to its prior value"
- self updateMapName:
- ((Updaters at: MCMcmUpdater defaultUpdateURL) updateMapName) ].
!
Item was changed:
----- Method: MCMcmUpdater class>>updateFromRepository:baseName: (in category 'updating') -----
updateFromRepository: updaterUrlKey baseName: baseName
"Update using an MCMcmUpdater identified by updaterUrlKey, and using
update map baseName"
"MCMcmUpdater
updateFromRepository: 'http://squeaksource.com/MCUpdateTest'
baseName: 'update' "
+ ^ self updateFromRepository: updaterUrlKey baseName: baseName interactive: true!
- ^ (self updateMapNamed: baseName repository: updaterUrlKey)
- doUpdate!
Item was added:
+ ----- Method: MCMcmUpdater class>>updateFromRepository:baseName:interactive: (in category 'updating') -----
+ updateFromRepository: updaterUrlKey baseName: baseName interactive: interactive
+ "Update using an MCMcmUpdater identified by updaterUrlKey, and using
+ update map baseName"
+
+ "MCMcmUpdater
+ updateFromRepository: 'http://squeaksource.com/MCUpdateTest'
+ baseName: 'update'
+ interactive: false "
+
+ ^ (self updateMapNamed: baseName repository: updaterUrlKey)
+ doUpdate: interactive!
Item was changed:
----- Method: MCMcmUpdater class>>updateFromServer (in category 'updating') -----
updateFromServer
"Update the image by loading all pending updates from the server."
+ ^self default doUpdate: true
- ^self default doUpdate
!
Item was removed:
- ----- Method: MCMcmUpdater>>doUpdate (in category 'updating') -----
- doUpdate
- "Update the image by loading all pending updates from the server. If this is
- the default updater for the system, update the system version when complete.
- Flush all caches. If a previous download failed this is often helpful"
-
- ^self doUpdate: true
- !
Item was changed:
----- Method: MCMcmUpdater>>doUpdate: (in category 'updating') -----
doUpdate: interactive
"Update the image by loading all pending updates from the server. If this is
the default updater for the system, update the system version when complete.
If interteractive use a modal notifier, otherwise only update the transcript.
Flush all caches. If a previous download failed this is often helpful"
+ | config previousUpdateLevel ensureTranscriptSetting |
- | config previousUpdateLevel |
previousUpdateLevel := SystemVersion current highestUpdate.
+ MCFileBasedRepository flushAllCaches.
+ ensureTranscriptSetting := MCConfiguration ensureOpenTranscript.
+ [ MCConfiguration ensureOpenTranscript: interactive.
- MCFileBasedRepository flushAllCaches.
config := self updateFromRepository.
config ifNil: [
interactive ifTrue: [ ^self inform: 'Unable to retrieve updates from remote repository.' translated ].
Transcript cr; show: '========== Unable to retrieve updates from remote repository. ==========' translated; cr.
^ self ].
MCMcmUpdater default == self
ifTrue: [
config setSystemVersion.
interactive ifTrue: [
self inform: ('Update completed.\\Version: {1}\Update: {3}{2}\\Url: {4}\Map: ''{5}''{6}' translated withCRs format: {
SystemVersion current version.
SystemVersion current highestUpdate.
previousUpdateLevel = SystemVersion current highestUpdate
ifTrue: ['']
ifFalse: [previousUpdateLevel asString, ' -> '].
self repository.
MCMcmUpdater updateMapName.
SystemVersion current description ifEmpty: [''] ifNotEmpty: [:d | String cr, String cr, d]})].
Transcript cr;
show: '========== Update completed: ' translated;
show: previousUpdateLevel;
show: ' -> ' ;
show: SystemVersion current highestUpdate;
show: ' =========='; cr ]
ifFalse: [
interactive
ifTrue: [ self inform: 'Update completed.' ].
+ Transcript cr; show: '========== Update completed. ==========' translated; cr ] ]
+ ensure: [ MCConfiguration ensureOpenTranscript: ensureTranscriptSetting].
+
- Transcript cr; show: '========== Update completed. ==========' translated; cr ]
!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1623.mcz
==================== Summary ====================
Name: Morphic-mt.1623
Author: mt
Time: 16 February 2020, 12:30:22.001951 pm
UUID: 7ee7b9be-f7ef-47b1-a3cb-418c45fb969f
Ancestors: Morphic-mt.1622
Fixes occasional error in lists that want to show the balloon text for items.
Thanks to Jakob (jr) for the tip!
=============== Diff against Morphic-mt.1622 ===============
Item was changed:
----- Method: PluggableListMorph>>balloonText (in category 'accessing') -----
balloonText
"Overridden to send selector to model and not self. Do not use #perform:orSendTo: because super does more than just the send.."
self getHelpSelector ifNotNil: [:selector |
+ (self model respondsTo: selector) ifTrue: [
+ | modelIndex |
+ (modelIndex := self modelIndexFor: self hoverRow) > 0 ifTrue: [
+ ^ self model perform: selector with: modelIndex]]].
- ((self model respondsTo: selector) and: [self hoverRow > 0]) ifTrue: [
- ^ self model perform: selector with: (self modelIndexFor: self hoverRow)]].
^ super balloonText!
Marcel Taeumel uploaded a new version of Services-Base to project The Trunk:
http://source.squeak.org/trunk/Services-Base-jr.68.mcz
==================== Summary ====================
Name: Services-Base-jr.68
Author: jr
Time: 16 February 2020, 10:22:29.735993 am
UUID: 03c9d902-3e2f-9246-817a-004adeefea60
Ancestors: Services-Base-eem.67
Small discoverability fixes to services class comments.
=============== Diff against Services-Base-eem.67 ===============
Item was changed:
Preferences subclass: #ServicePreferences
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Services-Base-GUI'!
+ !ServicePreferences commentStamp: 'jr 2/16/2020 10:19' prior: 0!
+ I store the preferences related to the services framework. The preferences are editable via the Services Browser, based on Hernan Tylim's Preference Browser.
- !ServicePreferences commentStamp: 'rr 7/10/2006 15:36' prior: 0!
- I store the preferences related to the servicse framework. The preferences are editable via the Services Browser, based on Hernan Tylim's Preference Browser.
The main preference categories for services are:
-- keyboard shortcuts -- : several text preferences, one per keyboard shortcuts. To edit them, enter a service identifier (equal to the method name under which it is defined in its ServiceProvider), and accept with alt-s or enter
-- menu contents -- : All the service categories in the image have a text preference under here. To edit it, enter the services identifiers you wish to put in this category, separating them with a single space character. The order is important: it defines the order of the items in menus.
-- settings -- : general boolean preferences.
Then there is a preference category for each provider in the image. Under each, you will find:
A boolean preference for each service in the image. If it is false, the service will not appear in menus.
The text preference for each service category defined by the service provider. This is the same as the one appearing in the menu contents preference category.!
Item was changed:
Object subclass: #ServiceProvider
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Services-Base'!
+ !ServiceProvider commentStamp: 'jr 2/16/2020 10:20' prior: 0!
- !ServiceProvider commentStamp: 'rr 7/10/2006 15:08' prior: 0!
A ServiceProvider references services that are relevant to a given application.
Each application that wishes to use the Services framework must subclass a ServiceProvider.
This class must define a 'services' method category.
Each method implemented in this category will be automatically called by the framework.
Each of these method should be a unary message (taking no argument), and return a fully initialised instance of ServiceAction or ServiceCategory. There are three possible patterns:
1)
serviceIdentifierAndMethodName
^ ServiceAction
text: 'Menu item text'
button: 'Button text'
description: 'Longer text that appears in help balloons'
action: [:r | "Code block fetching data from the requestor instance, r, that is passed to the block"]
2)
serviceIdentifierAndMethodName
^ ServiceAction
text: 'Menu item text'
button: 'Button text'
description: 'Longer text that appears in help balloons'
action: [:r | "Code block fetching data from the requestor instance, r, that is passed to the block"]
condition: [:r | "second block returning true if the service can be used at the time being, false otherwise. Data can still be fetched from the requestor instance"]
3)
methodNameAndServiceCategoryId
^ ServiceCategory
text: 'Menu text'
button: 'Button text'
description: 'Longer descriptive text appearing in help balloons'
The organisation of services into categories, and the services bound to keyboard shortcuts are
+ specified using the Services Browser (see the comment on the class ServicePreferences for more details). When editing preferences, they are saved as methods on the ServiceProvider, all defined
- specified using the Services Browser (see the comment on the class ServicesPreferences for more details). When editing preferences, they are saved as methods on the ServiceProvider, all defined
in the 'saved preferences' method category. Each of thesse methods stores preferences that the provider can replay.
!
Marcel Taeumel uploaded a new version of MorphicExtras to project The Trunk:
http://source.squeak.org/trunk/MorphicExtras-mt.269.mcz
==================== Summary ====================
Name: MorphicExtras-mt.269
Author: mt
Time: 14 February 2020, 3:07:58.332667 pm
UUID: 825d4289-5a5b-3e4e-8828-f518d1a1a8c3
Ancestors: MorphicExtras-mt.268
Some fixes in scrap book and book morph in support of Etoys.
=============== Diff against MorphicExtras-mt.268 ===============
Item was changed:
----- Method: BookMorph>>insertPageLabel:morphs: (in category 'insert and delete') -----
insertPageLabel: labelString morphs: morphList
| m c labelAllowance |
self insertPage.
labelString ifNotNil:
+ [m := labelString asMorph.
- [m := (TextMorph new extent: currentPage width@20; contents: labelString).
m lock.
m position: currentPage position + (((currentPage width - m width) // 2) @ 5).
currentPage addMorph: m.
labelAllowance := 40]
ifNil:
[labelAllowance := 0].
"use a column to align the given morphs, then add them to the page"
c := AlignmentMorph newColumn wrapCentering: #center; cellPositioning: #topCenter.
c addAllMorphs: morphList.
c position: currentPage position + (0 @ labelAllowance).
currentPage addAllMorphs: morphList.
^ currentPage
!
Item was changed:
----- Method: BooklikeMorph>>fullControlSpecs (in category 'page controls') -----
fullControlSpecs
^ {
#spacer.
#variableSpacer.
{'-'. #deletePage. 'Delete this page' translated}.
#spacer.
{'«'. #firstPage. 'First page' translated}.
#spacer.
{'<'. #previousPage. 'Previous page' translated}.
#spacer.
{'·'. #invokeBookMenu. 'Click here to get a menu of options for this book.' translated}.
#spacer.
{'>'. #nextPage. 'Next page' translated}.
#spacer.
{ '»'. #lastPage. 'Final page' translated}.
#spacer.
{'+'. #insertPage. 'Add a new page after this one' translated}.
#variableSpacer.
+ {'o'. #fewerPageControls. 'Fewer controls' translated}
- {'³'. #fewerPageControls. 'Fewer controls' translated}
}
!
Item was changed:
----- Method: BooklikeMorph>>makePageControlsFrom: (in category 'page controls') -----
makePageControlsFrom: controlSpecs
"From the controlSpecs, create a set of page control and return them -- this method does *not* add the controls to the receiver."
| c col row |
+ c := (color saturation > 0.4) ifTrue: [color slightlyLighter] ifFalse: [color slightlyDarker].
- c := (color saturation > 0.1) ifTrue: [color slightlyLighter] ifFalse: [color slightlyDarker].
col := AlignmentMorph newColumn.
col color: c; borderWidth: 0; layoutInset: 0.
col hResizing: #spaceFill; vResizing: #shrinkWrap; extent: 5@5.
row := AlignmentMorph newRow.
row color: c; borderWidth: 0; layoutInset: 0.
row hResizing: #spaceFill; vResizing: #shrinkWrap; extent: 5@5.
controlSpecs do: [:spec | | lastGuy b |
spec == #showDescription ifTrue: [row addMorphBack: self makeDescriptionViewer].
spec == #pageNumber ifTrue: [row addMorphBack: self makePageNumberItem].
spec == #spacer ifTrue: [row addTransparentSpacerOfSize: (10 @ 0)].
spec == #variableSpacer ifTrue: [
row addMorphBack: AlignmentMorph newVariableTransparentSpacer].
spec class == Array ifTrue: [
spec first isSymbol
ifTrue: [b := ThreePhaseButtonMorph labelSymbol: spec first]
ifFalse: [b := SimpleButtonMorph new borderWidth: 2;
+ borderColor: Color black; color: Color white.
- borderColor: Color black; color: Color veryLightGray.
b label: spec first font: Preferences standardMenuFont].
b target: self; actionSelector: spec second; setBalloonText: spec third.
(spec atPin: 4) = #border
ifTrue: [b actWhen: #buttonDown]
ifFalse: [b borderWidth: 0]. "default is none"
row addMorphBack: b.
(((lastGuy := spec last asLowercase) includesSubstring: 'menu') or:
[lastGuy includesSubstring: 'designations'])
ifTrue: [b actWhen: #buttonDown]]]. "pop up menu on mouseDown"
col addMorphBack: row.
^ col!
Item was changed:
----- Method: BooklikeMorph>>shortControlSpecs (in category 'page controls') -----
shortControlSpecs
"Answer specs defining the widgets in the short form of the control panel."
^ {
+ {#MenuIcon. #invokeShortBookMenu. 'Click here to get a menu of options for this book.' translated}.
- #spacer.
#variableSpacer.
+ {#PrevPage. #previousPage. 'Previous page' translated}.
- {'<'. #previousPage. 'Previous page' translated}.
#spacer.
+ #pageNumber.
- {#MenuIcon. #invokeShortBookMenu. 'Click here to get a menu of options for this book.' translated}.
#spacer.
+ {#NextPage. #nextPage. 'Next page' translated}.
- {'>'. #nextPage. 'Next page' translated}.
#spacer.
#variableSpacer.
+ {'...'. #showMoreControls. 'More controls' translated}
- {#RightCaret. #showMoreControls. 'More controls' translated}
}
!
Item was changed:
----- Method: ScrapBook>>addToTrash: (in category 'scraps') -----
addToTrash: aMorph
"Paste the object onto a page of the system Trash book, unless the preference is set to empty the trash immediately."
| aPage |
TrashCanMorph preserveTrash ifFalse: [^ self].
aMorph position: book pages first position + (0@40).
book pages do: [:pp |
(pp submorphs size = 1 and: [pp hasProperty: #trash]) ifTrue: "perhaps remove that property here"
["page is blank"
^ pp addMorph: aMorph]].
+ aPage := book insertPageLabel: ('{1} {2}' format: Time dateAndTimeNow)
- aPage := book insertPageLabel: Time dateAndTimeNow printString
morphs: (Array with: aMorph).
aPage setProperty: #trash toValue: true!
Item was changed:
----- Method: ScrapBook>>scrapBook (in category 'scraps') -----
scrapBook
| header aButton label |
^ book ifNil: [
+ book := BookMorph new pageSize: 300@300; setNameTo: 'scraps' translated.
+ book addCornerGrips.
- book := BookMorph new pageSize: 200@300; setNameTo: 'scraps' translated.
book color: Color yellow muchLighter.
book borderColor: Color darkGray; borderWidth: 2.
book removeEverything; showPageControls; insertPage.
+
header := AlignmentMorph newRow wrapCentering: #center; cellPositioning: #leftCenter.
header setProperty: #header toValue: true.
+ header addMorph: (aButton := ThreePhaseButtonMorph labelSymbol: #'Halo-Collapse').
- header addMorph: (aButton := SimpleButtonMorph new label: 'O' font: Preferences standardButtonFont).
aButton target: book;
- color: Color tan;
actionSelector: #delete;
setBalloonText: 'Close the trashcan.\(to view again later, click on any trashcan).' withCRs translated.
-
header addMorphBack: AlignmentMorph newVariableTransparentSpacer beSticky.
header addMorphBack: (label := UpdatingStringMorph new target: self) beSticky.
label getSelector: #trashTitle; useStringFormat; step.
header addMorphBack: AlignmentMorph newVariableTransparentSpacer beSticky.
+ header addMorphBack: (aButton := ThreePhaseButtonMorph labelSymbol: #'Halo-Dismiss').
+ aButton target: self;
+ actionSelector: #maybeEmptyTrash;
- header addMorphBack: (aButton := SimpleButtonMorph new label: 'E' translated font: Preferences standardButtonFont).
- aButton target: self; color: Color veryLightGray; actionSelector: #maybeEmptyTrash;
setBalloonText: 'Click here to empty the trash.' translated.
+ book currentPage
+ layoutPolicy: TableLayout new;
+ addMorph: (TextMorph new
+ contents: 'Objects you drag into the trash will automatically be saved here, one object per page, in case you need them later. To disable this feature set the "preserveTrash" Preference to false.\\You can individually expunge objects by hitting the "-" control (behind "..."). You can empty out all the objects in the trash can by hitting the "X" button at top right.' withCRs translated;
+ hResizing: #spaceFill).
- book currentPage addMorph: (TextMorph new contents: 'Objects you drag into the trash will automatically be saved here, one object per page, in case you need them later. To disable this feature set the "preserveTrash" Preference to false.\\You can individually expunge objects by hitting the - control, and you can empty out all the objects in the trash can by hitting the "E" button at top right.' withCRs translated
- wrappedTo: 190).
book addMorphFront: header.
book setProperty: #scraps toValue: true].!
Item was changed:
----- Method: ScrapBook>>trashTitle (in category 'scraps') -----
trashTitle
+
+ ^ 'T R A S H' translated!
- | label pgs |
- label := 'T R A S H' translated.
- ^ (pgs := book pages size) < 2
- ifTrue:
- [label]
- ifFalse:
- [label, (' ({1} pages)' translated format:{pgs})]!
Item was changed:
+ ----- Method: TrashCanMorph>>acceptDroppingMorph:event: (in category 'dropping/grabbing') -----
- ----- Method: TrashCanMorph>>acceptDroppingMorph:event: (in category 'layout') -----
acceptDroppingMorph: aMorph event: evt
SoundService soundEnabled
ifTrue: [TrashCanMorph preserveTrash
ifTrue: [self class playDeleteSound]
ifFalse: [self playSoundNamed: 'scratch']].
evt hand visible: true.
self state: #off.
aMorph delete.
aMorph == ScrapBook default scrapBook
ifFalse: [ScrapBook default addToTrash: aMorph removeHalo]!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1620.mcz
==================== Summary ====================
Name: Morphic-mt.1620
Author: mt
Time: 13 February 2020, 1:50:20.180714 pm
UUID: 6bf64818-7dff-9846-bba7-e19359473664
Ancestors: Morphic-kfr.1619
Adds documentation to that modal-dialog issue related to restoring the mouse focus after dialog invocation.
=============== Diff against Morphic-kfr.1619 ===============
Item was changed:
----- Method: DialogWindow>>getUserResponse (in category 'running') -----
getUserResponse
| hand world |
self message ifEmpty: [messageMorph delete]. "Do not waste space."
self paneMorph submorphs
ifEmpty: ["Do not waste space and avoid strange button-row wraps."
self paneMorph delete.
self buttonRowMorph wrapDirection: #none].
hand := self currentHand.
world := self currentWorld.
self fullBounds.
self moveToPreferredPosition.
self openInWorld: world.
hand showTemporaryCursor: nil. "Since we are out of context, reset the cursor."
hand keyboardFocus in: [:priorKeyboardFocus |
hand mouseFocus in: [:priorMouseFocus |
self exclusive ifTrue: [hand newMouseFocus: self].
hand newKeyboardFocus: self.
[[self isInWorld] whileTrue: [world doOneSubCycle]]
ifCurtailed: [self cancelDialog].
hand newKeyboardFocus: priorKeyboardFocus.
+
+ self flag: #discuss. "Since 2016 we are having this *ping pong* between (a) restoring the prior mouse focus and (b) just clearing it globally. The former solution makes more sense while the latter fixes issues with some modal dialogs. We have to investigate this further."
+ hand releaseMouseFocus.
+ "hand newMouseFocus: priorMouseFocus."]].
- hand releaseMouseFocus]].
^ result!