Seaside 3.0.3
Seaside 3.0.3, a patch release, is out:
We are pleased to announce the release of Seaside 3.0.3. This is a bugfix release for Seaside 3.0. We recommend all users of Seaside 3.0 to update.
Technorati Tags: seaside
. .
The author of this blog, James Robertson, passed away in April 2014. This blog is being maintained by David Buck (david@simberon.com).
Seaside 3.0.3, a patch release, is out:
We are pleased to announce the release of Seaside 3.0.3. This is a bugfix release for Seaside 3.0. We recommend all users of Seaside 3.0 to update.
Technorati Tags: seaside
Last month Julian Fitzell gave a talk on Seaside at OSDC in France. I've embedded the talk below - it starts in French, but flips over to English pretty quickly. Here's a summary for the talk:
Are you tired of marshaling state, mapping URLs, and making sure your form fields all have unique element IDs? Do you long for a better way to develop for the web, without editing XML files? Do you ever wish complex online applications actually let you use the Back button? Seaside frees you from these burdens, leaving you to focus on creating the applications that can make or break your business.
[OSDC.fr 2010] Seaside - Why Should You Care? (by Julian Fitzell) from OSDC.fr on Vimeo.
One of the things I've been asked to look at here is build automation. Right now, all builds are done manually, using RTP - and sometimes, based on various things going on, they need multiple builds done per day. As you can imagine, that takes up a lot of staff time, and adds in an error prone personal component to the process.
Now, I'm hardly an expert in such things, and for that matter, there are entire toolsets devoted to this field. Having said that, I do have a set of build scripts for BottomFeeder, so I have done some work here. When I sat down to look at what I do for Bf, I realized that while I've automated pieces, I haven't automated everything. So, I created a small (very small) tool to tie my process together. We'll see whether or not it scales up well enough to use for the problem at work, but that's in the future.
Right now, here's how I do BottomFeeder builds:
Not as automated as I'd like :) I wrapped the first three things up with the tool I created - the last bit will require some research on my part - I haven't done unattended sftp in a shell script before, and unlike stock FTP, it's not something I can do in Smalltalk out of the box. So how does it work? Simple, really - I have a key=value ini file that describes each script that will run. The one for BottomFeeder looks like this:
[ScriptInfo] starter='./startvw ' script='build-bf-non-windows.st' assertion='build-bf-non-windows-assertion.st' isVWCommand=true [ScriptInfo] starter='./startvw ' script='compress-bf-image.st' assertion='compress-bf-image-assertion.st' isVWCommand=true [ScriptInfo] starter='./startvw ' script='executeBuildScript.st' assertion='executeBuildScripyt-assertion.st' isVWCommand=true
Basically, each section describes how to run the script, whether it's a VW script or not, and an assertion script to go with the build piece. That assertion piece is just a small bit a of Smalltalk that should return a boolean, explaining whether the associated build script worked or not. Then I put together a (very simple) UI that lets me pick a script to use, and see the results. Heck, I even have tests :) That window looks like this, after I ran my test script:
That's pretty much it, really - there's plenty that could be done, and it's hardly the best build system in the world - but it suits my purposes well enough, and automates what was a tedious build process. Whether it scales up for a real project - I'll find out soon enough :) If you're interested in taking a look, load the "BuilderBundle" bundle from the public store repository. I'm happy to hear any comments, good, bad, or indifferent.
Technorati Tags: visualworks, builds, build tool
Yesterday, I pushed up a post detailing a hack I did to make drag/drop in VisualWorks listboxes work more like they are expected to work. One problem though; my "fix" pretty much breaks select on down, which isn't really what you want.
As is usually the case with such things, if the fix seems overly complex, you're probably doing something wrong - and I certainly was here. The problem comes up in EmulatedSequenceTracker>>setUpDragDropFor:
setUpDragDropFor: aMouseButtonEvent "If we are doing drag and drop, we don't have to do the preparation work" self outside: false. (controller selectOnDownWithDrag and: [self view selectionIndex ~= self view targetIndex]) ifTrue: [(self isTryingToGrabPreviouslySelectedAreaWith: aMouseButtonEvent) ifFalse: [self controller toggleTargetWithEvent: aMouseButtonEvent]. selectionDone := true]
Notice the change from what I posted yesterday. Instead of outright ignoring the selection, I added a test - and the test method looks like this:
isTryingToGrabPreviouslySelectedAreaWith: anEvent "if the user is trying to grab a previously selected area, and drag/drop is on, answer true. Otherwise answer false" | index indices | controller wantsToDrag ifFalse: [^false]. index := self view targetIndex. indices := self view selectionChannel value. (self eventHasKeyboardOptionsDown: anEvent) ifTrue: [^false]. ^(indices includes: index)
Basically, you ask three questions:
That test on keyboard modifier looks like this:
eventHasKeyboardOptionsDown: anEvent "we want keyboard modifiers to still affect the selection - the #respondsTo: test makes this work in both VW 7.6 (and older) and VW 7.7.1" ^(anEvent respondsTo: #ctrlOrCommandDown) ifTrue: [anEvent ctrlOrCommandDown | anEvent shiftDown] ifFalse: [anEvent ctrlDown | anEvent altDown | anEvent shiftDown]
With that, it looks like things respond the way you would expect, and select on down works (unlike the hack I posted yesterday). I also think this is closer to a supportable fix - although I suspect a full rewrite of the controller and tracker are still a decent idea. You can find the code in the public repository as MultiSelectPatch. Kind of outside my scope though :)
Spotted in comp.lang.smalltalk:
Christmas edition of Aida/Web is on the way and here is first beta, for Squeak/Pharo and VisualWorks. Instruction how to install it are here
Looks like the biggest new thing is direct support for mobile platforms, but there's a lot going on here - follow the link for details.
Travis has been thinking about sort functions in Smalltalk, and how to follow the same patterns shown in SymbolValue and Block culling:
Since the introduction of SymbolValue and Block culling, one of the things I've chased is how to do this same style of programming with sorting. For most sorting cases, you have a series of objects that you want to sort on some particular attribute. Maybe a sequence of customers you'd like to sort by name.
Travis goes into the approach he picked - go read the whole thing for the details. I do like this summation:
I sat down last night, and with tests, put together a TAG-SortFunctions package, published in the Cincom Public Repository. The basic idea was to use an object. Time and time and time again over the years, I rediscover the principle "there's an object waiting to be birthed here!"
A lot of sins in Smalltalk code can be solved by remembering to create a new object when it's useful to do so. It's not like they cost money :)
Technorati Tags: sorting, visualworks
One of the small annoyances in VisualWorks is the way selection works with listboxes when you set them for:
That last thing is what doesn't work out of the box - instead, when you first click the left button, the selected group is de-selected, and the one thing you were pointing at when you wanted to do a drag operation becomes the new selection.
As you might guess, given the way most end user tools now work, end users are not entirely pleased with this turn of events. So... It was off to controller land. A few minutes of investigation told me that multi-selection listboxes use the class EmulatedSequenceController, and I started trawling through the code.
Now, other than patching some of the more egregious flaws in the way Datasets work, I haven't done a lot of hacking on controllers. So it took me a bit of rathole diving before I realized that the problem was in EmulatedSequenceTracker, which works in conjunction with the controller. If you look at the #redButtonPressedEvent: method there (with a flashback to Xerox mice tossed in), you find that you end up calling down to #setUpDragDropFor:
setUpDragDropFor: aMouseButtonEvent "If we are doing drag and drop, we don't have to do the preparation work" self outside: false. (controller selectOnDownWithDrag and: [self view selectionIndex ~= self view targetIndex]) ifTrue: [self controller toggleTargetWithEvent: aMouseButtonEvent. selectionDone := true]
The problem resides in the first statement in the block - the controller is told to toggle the selection, and it dutifully does so. It's only later in the call chain that drag/drop is checked for, by which time the selection has been reset. So... I hacked up three methods in EmulatedSequenceController to make that happen on red button up instead of on red button down - note the extra checks for whether we want to drag or not; without that, you get some truly weird behavior:
setUpDragDropFor: aMouseButtonEvent "If we are doing drag and drop, we don't have to do the preparation work" "JR 12/13/10: For multi-select, don't toggle target on red down. Instead, that should happen on red up" self outside: false. (controller selectOnDownWithDrag and: [self view selectionIndex ~= self view targetIndex]) ifTrue: ["self controller toggleTargetWithEvent: aMouseButtonEvent." selectionDone := true]
redButtonReleasedEvent: aMouseButtonEvent self sensor ungrabMouseEventFor: self. self finishSelectionForEvent: aMouseButtonEvent. "JR 12/13/10 - moved out of the #redButtonPressedEvent: method. For multi-select lists, if drag/drop is on, we want selections toggled on mouse up" self wantsToDrag ifTrue: [self controller toggleTargetWithEvent: aMouseButtonEvent. selectionDone := true]
This method below is mostly the same as the inherited version, with the extra ifFalse: clause at the end:
setUpFor: aMouseButtonEvent "If we are doing drag and drop, we don't have to do the preparation work" "JR 12/13/10 - When not dragging, actually make the selection" | index | selectionDone := false. startPoint := self cursorPointFor: aMouseButtonEvent. self outside: false. (index := self view numberOfElements) = 0 ifTrue: [^self]. index := self controller findElementFor: (self cursorPointFor: aMouseButtonEvent). self view targetIndex: index. self wantsToDrag ifTrue: [self setUpDragDropFor: aMouseButtonEvent]"This API is obsolete. Use cursorPointFor: instead." ifFalse: [self controller toggleTargetWithEvent: aMouseButtonEvent. selectionDone := true]
In the button release method, I copied over both lines from the block in #setUpDragDropFor:. After that, things worked the way I wanted them to - with multiple selections only deselecting on mouse button up. Kind of amusing that such a small fix took me most of the day to track down, but there you go :)
Technorati Tags: visualworks, listbox
I've upgraded BottomFeeder from one rev of VW to another multiple times now, so I have a pretty good feel for looking at overrides - but on this new job, I wanted something bit more formal than "eyeball the bundle and look for red, bolded classes". So, I wrote a small reporter that starts out with this, in the older version of VW:
| overriddenClasses records | overriddenClasses := SmalltalkWorkbench sortedClasses select: [:each | Override isOverriddenClassOrNameSpace: each].
That collects all of the classes in the current image where the class definition is an override. Usually, that means that a developer has added one or more instance variables to the class for an application (or tool) specific reason - although in this app, there are two such overrides where the class definition hasn't changed. That likely means someone bailed on a modification at some point, but neglected to remove the override.
Anyway - with that information in hand, I just bossed out some basic data - the full name of the class (i.e., full namespace qualification) and the array of instance variable names. Then I loaded that information into a 7.7.1 image, got the class from the string name, and grabbed the array of instance variables for each of those. With the two sets of data sitting in an object, it's easy to do some basic comparisons. Useful, and not at all difficult.
Technorati Tags: visualworks, overrides
Sean Denegris has ported some code out of Sophie and into Squeak:
song := StreamingMP3Sound onFileNamed: '/path/to/yourFavorite.mp3'. song play. "song pause."
There are some caveats about the level of testing and such, but that's pretty cool.
Technorati Tags: squeak
A shell for GLASS - and a video to see how it works. Cool stuff.
| Previous | Next | (1106 total) |