2007/06/28

Westinghouse Service - at last

Can it be that our Westinghouse service saga is finally at an end?

Yesterday Westinghouse finally sent us a replacement for our defective LVM37w3.

The new unit is probably a refurb. The serial number is definitely different from that of the one we sent in for repair, and it displays a different message when a new video source is detected.

For the record, it took 55 days for Westinghouse to repair/replace our broken monitor. With that kind of turn-around time, I'd have to advise any prospective buyer to go with a different brand.

2007/06/26

Subversion, Bazaar and Mac document bundles

Subversion has problems dealing with Mac applications which store their documents as bundles (directory trees). The first is that such bundles may contain an icon preview file, "Icon\r", whose filename contains a carriage return. The second is that the bundle may contain files representing e.g. pasted graphics, which come and go as the document is edited. Subversion cannot, as far as I know, add and remove such nested files without user intervention.

Some applications, like OmniGraffle, offer a workaround for the hierarchical document structure. Other applications do not, e.g. LineForm, and VoodooPad, and Apple's own KeyNote and TextEdit.

(That's not quite true. The VoodooPad Lua Plugin Snippets page shows a Lua plugin which handles the hierarchical document problem by automatically adding new documents, removing deleted documents, and committing changes, for a designated directory.)

Does bzr handle either of these problems more gracefully than subversion?

Testing shows that bzr handles "Icon\r" with aplomb. However, it does not automatically add any new nested files to the repository. It's up to you to add them manually, just as in subversion.

2007/06/20

Bug with jQuery 1.1.2, Interface 1.2, Slider with fractions

I have a Slider with fractions and an onSlide handler. Sometimes when the handler is invoked, the reported value for xProc seems to be "lagging" -- it seems to be the value from just before the slider jumped to its current position.

Here's a fragment demonstrating the problem:


<div id="slider_frame">
<div id="bar">
<div id="indicator" class="Indicator"></div>
</div>
</div>
<p id="msg"></p>
...
onSlide: function(xProc, yProc, x, y) {
var fraction = x / this.dragCfg.containerMaxx;
var nearest = Math.round(x / 4) * 4;
var expected = Math.round(nearest * 100 / this.dragCfg.containerMaxx);
$("#msg").html("Expected " + expected + ", got " + xProc);


In the web app where I've encountered this problem, I'm working around it by recomputing the xProc value inside the onSlide handler:
    xProc = parseInt(x * 100 / this.dragCfg.containerMaxx);


Here's a more complete example:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>interactive_problem_demo</title>
<style type="text/css" media="screen">
#slider_frame {
border: 1px inset;
position: relative;
width: 300px;
height: 12px;
}
#bar {
position: absolute;
width: 300px;
height: 12px;
background-color: #99a;
}
#indicator {
position: absolute;
width: 6px;
height: 12px;
background-color: #eef;
}
#msg {
max-width: 300px;
}
.Good {
background-color: #0f0;
}
.Bad {
background-color: #f99;
}
</style>
</head>
<body>
<div id="slider_frame">
<div id="bar">
<div id="indicator" class="Indicator"></div>
</div>
</div>
<p id="msg" class="Good">Please click in the trough.</p>

<script src="../../../shared/js/jquery/jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="../../../shared/js/jquery/interface.js" type="text/javascript" charset="utf-8"></script>
<script src="../../../shared/js/jquery/dimensions.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript" charset="utf-8">
<!--
$(document).ready(function() {
var f = 5;
var slider = $("#bar").Slider({
accept: "#indicator",
fractions: f,
onSlide: function(xProc, yProc, x, y) {
var fraction = x / this.dragCfg.containerMaxx;
var expected = Math.round(100 * fraction / (f - 1)) * (f - 1);
$("#msg").html("Expected " + expected + ", got " + xProc);
$("#msg").removeClass("Good Bad");
$("#msg").addClass(xProc == expected ? "Good" : "Bad");
}
})
});
//-->
</script>
</body>
</html>

2007/06/19

Mail.app, pasted graphics, and Windows recipients

[Draft]

Summary

When composing in Mail.app:

  • if you attach a file, its format is preserved
  • If you paste a screen capture, some capture formats will be translated to TIFF
  • Some Windows users cannot view TIFF mail attachments
  • This behavior seems to apply to other OS X applications as well
Here's a table showing how Mail.app translates pasted graphics, under Mac OS X 10.4.9:
Screen CapturePasted Format
GIFTIFF
JPGTIFF
PDFPDF
PNGPNG
TIFFTIFF

Gory Details

If I paste screenshots into my Mail.app messages, some Windows recipients cannot see those screenshots. When sending to these recipients I have to use a much more tedious process:
  1. Save screenshot to file
  2. Compose mail
  3. Click "Attach"
  4. Browse to saved file
Others are dealing with the same problem. Witness this thread at macosxhints.com.

Is the problem that the pasted graphics are set to display inline? (Content-Disposition: inline) No. No matter how I make an attachment, whether through pasting or through the Attach button, Mail.app always sets Content-Disposition to inline. And Windows users can see some attachments.

Is there anything relevant in ~/Library/Preferences/com.apple.mail.plist? Not as far as I can tell.

I have changed my default screen capture format, following the instructions in this macosxhints article:
    defaults write com.apple.screencapture type format
killall SystemUIServer

My format is set to jpeg. That seems to be the problem. Mail.app translates pasted JPEG images to TIFF. Attached JPEG images retain their format.

I'm not sure about the reasons for this, but Preview.app seems to confirm the following weirdness: If you do a screen capture to the clipboard, some formats such as JPG get converted to PICT. If you do the screen capture to a file, then the format you specify is the format used in the capture file.

2007/06/14

Textmate: "Snippet Commands" and Placeholders

Draft

Textmate snippets are chunks of templated text, sprinkled with placeholders of the form

${1:default value}
When you invoke a snippet, it injects text into the current document, and it lets you tab through all of the placeholder fields and edit their values.

Sometimes you need to generate a lot of stubbed-out files in one go, e.g. when creating a Firefox extension. Snippets aren't so useful here, but Textmate commands are. At their simplest these are just scripts (pick a language; I like Python) which you invoke from within Textmate.

It sure would be nice to be able to use placeholders in those stubbed-out files, and to use Textmate as a sort of form editor. For example, the install.rdf file in a Firefox extension bundle has about eight fields which you might want to edit. You can generate default values for these fields when stubbing out the bundle, but several of them (e.g. the bundle ID, or your real-world name) might require customization.

There's a really simple way to create a Textmate command that lets you do placeholder editing on any file.

Open Textmate's bundle editor. Create a new bundle. Name it Fill in the blanks. In the command editor pane, set Save: to Current File. Put this text into the Command(s): text area:
cat "$TM_FILEPATH"
Set Input: to Selected Text or Document. Set Output: to Insert as Snippet.

Save your changes by selecting a different bundle in the bundle editor.

Now imagine you have written a script which generates a stub file. Wherever the file contains a value that you might want to change manually, put that value inside a placeholder, e.g.
${1:default value}
Run the script to generate your stub file. Open the stub in Textmate. Select all of the text, then invoke your "Fill in the blanks" bundle.

Voila! The contents of your stub file have not changed, but now you can tab from one placeholder field to the next, editing the values which your stub generator provided.

*sigh*

So many words for a simple procedure. I should put up a screencast on the Om OS X blog...

Procedure expects parameter '@statement' of type 'ntext/nchar/nvarchar'.

I just re-factored an SQL Server stored procedure to use sp_executesql. Lots of cut and paste. It looked almost identical to a sibling stored procedure, at least in terms of local variable declarations and parameter list declaration. So why, where the sibling stored procedure returned results, did this stored procedure generate this error message?

Procedure expects parameter '@statement' of type 'ntext/nchar/nvarchar'


Richard Dudley had the answer. I had inadvertently declared my @queryStr variable as varchar instead of nvarchar.

Implementing file download links

It's amazing how many basic web developer techniques I still don't know.

I want to provide a file download link. But the URL is not a static path like

http://some.server.com/some_file.csv

Instead it points to an ASP.NET or PHP page, e.g.
http://some.server.com/Download.aspx?item=blah
http://some.server.com/download.php?item=blah

And it returns dynamically-generated, plain-text, comma-separated-value content.

How do I convince Safari to download the file, rather than simply loading it in the browser window? How do I convince Firefox that the downloaded content is really text/csv and not a file of type php or aspx?

The answer, courtesy of the online PHP manual: use a content-disposition header.

To find the details, go to the PHP manual page and search for "Content-Disposition".

Safari / WebKit Feature Request

Google has this nice feature: select "some text" in a web page, right-click, and you see a menu item:

Search current search engine for "some text"
When you select the menu item, Firefox performs the search and presents the results in a new tab.

This behavior is really useful. For example, when you're reading a forum post in which someone cites an API or software product you've never heard of, you can go off and learn more about the citation without losing your place in the forum.

WebKit (and Safari3?) have a similar menu item. Of course, unless you've installed some 3rd-party extensions the search engine is always Google. But the really unfortunate thing is that the search results replace the current page.

Maybe there's a magic key combination which lets you override this behavior, but I haven't found it yet. It sure would be nice if Safari implemented this feature in the same way as Firefox.

2007/06/12

Where's the Clipboard Viewer in Windows XP?

I couldn't find a clipboard viewer anywhere in my XP Start Menu hierarchy. Once again, the web provides. From Where's the Clipboard Viewer in Windows XP?



  1. Click the Start menu button and open My Computer.

  2. Open your C drive. (It's listed in the Hard Disk Drives section.)

  3. Double-click on the Windows folder. (You might have to tell it to let you see what's inside.)

  4. Double-click on the System32 folder. (Again, you might have to tell it to let you see what's inside.)

  5. Scroll down the page until you locate a file named Clipbrd.

  6. Drag and drop the Clipbrd file onto your Start button.




2007/06/11

Shrinking your Visual Web Developer project databases

It's annoying that my web app's SQL Server 2005 database file is less than one megabyte in size; whereas the internal application database created by Visual Web Developer, with which I've never mucked directly, is over 10MB.

Of couse the blogosphere has known about this problem much longer than I have. And here's a handy solution:

Shut-Up and Smile : ASP.NET Membership Database Squish

This script does the equivalent of the SQL Server Management Studio's "Tasks->Shrink" menu item. I have a hard time using that menu item on my application's database file, perhaps because of file ownership issues. Whatever: this script smooshed things right down to size.

2007/06/08

Soot responsible for over 90% of polar warming?

Scientific American reports that soot - from smokestacks, vehicle tailpipes, and even forest fires[1] may be a major factor in polar warming.

Impure as the Driven Snow: Scientific American:

DIRTY TRICK:  Soot is three times more effective than carbon dioxide [...] at melting polar snow, triggering feedback loops that further accelerate polar warming.

In the atmosphere, such aerosols [as soot] can significantly cool the planet by scattering incoming radiation or helping form clouds that deflect incoming light. But on snow [...] such dark carbon [...] may be responsible for as much as 94 percent of Arctic warming.


[1] Why do they say "even"? Let them spend a typical summer in the southwest, and be amazed at the amount of soot a wildfire can dump into the air...

Seriously, the researchers cited in the article say that about 80% of the observed soot comes from human sources. I bet a lot of that comes from around Karaganda :)

Smokestack

2007/06/07

Modifying a wrong commit message in a svn/trac combo

Sometimes I screw up a commit comment in subversion, and need to fix it. I can never remember how to do so. 'svnadmin setlog' seems obviously the way to go, but when I try to use that command I get an error message:

svnadmin: Repository has not been enabled to accept revision propchanges;
ask the administrator to create a pre-revprop-change hook


Here's the right way to do it, including extra steps which make Trac aware of the change:
modifying a wrong commit message in a svn/trac combo

The need for the trac-sync step implies that trac uses a subversion commit hook to record the details of each subversion commit.

2007/06/05

SQL Server: Avoiding multiple record sets

I have a stored procedure which needs to execute other stored procedures in order to generate its results. Unfortunately, those nested stored procedures can perform SELECTs. The end result is that, instead of returning one record set, my stored procedure may return multiple record sets.

How to prevent this? According to http://databases.aspfaq.com/database/using-stored-procedures.html :

After the BEGIN command, we SET NOCOUNT ON -- this prevents interim statements from being returned as recordsets.


Does NOCOUNT really affect whether or not multiple record sets are returned? Not when you're dealing with nested execution of stored procedures...

The only solution I can find is to create a temporary table, in the calling stored procedure, and to dump the results of the called stored procedure into that temporary table, then to delete it.


CREATE TABLE [#unused] (foo REAL, bar REAL);
INSERT INTO [#unused] EXECUTE my_nested_sp @arg1, @arg2;
DROP TABLE [#unused];

Westinghouse service (?)

Last year we bought a Westinghouse LVM37w3. It's a great monitor, and it does a great job of displaying output from a Sony HD camcorder.

Well, it used to. Early this spring it started flaking out. After it had been on for awhile the backlight would suddenly go out, leaving us with audio and a pitch-black screen. To get the picture back we had to cycle the thing off and on again.

After reading a few anecdotes online, which claimed that others had cured this problem by resetting to factory defaults, we gave it a try. The change was noticeable. Now, as soon as the monitor was powered up, the backlight would go out.

Luckily the monitor was still, barely, under warranty. We called Westinghouse tech support (1-866 -287-5555), who said they would call us with an RMA number within a couple of days.

After a week, tired of waiting, I called them again. They had the RMA number and claimed they had left it on our answering machine. I wonder whose answering machine they really left it on, but no matter: we shipped off the unit at considerable expense (a couple hundred dollars).

It has been gone since May 3rd. Checking the status of the unit has been painful: call Westinghouse tech support, ask for a status update, hear the poor staffer on the other end explain that (s)he needs to submit a status request to the warehouse and to call back in two or three days.

For the past two weeks the answer has come back that the monitor has been repaired, but is still listed as "processing" by the warehouse. They will call me as soon as they have a UPS Ground tracking number. (They haven't called yet.) If I don't hear from them within a week, please call again for an update.

Something sure seems fishy here. Or at least incompetent.

MarsEdit 1.2: Growl, Picasa and Vox!

MarsEdit1.2.jpg

MarsEdit 1.2: Growl, Picasa and Vox!:

MarsEdit 1.2 is now available for download (or just ‘Check for Updates’ from the app). This is a free update for all registered MarsEdit users.

Three relatively big changes in this release: [...]

Picasa image uploads for Blogger.com. This is pretty transparent. Just select your Blogger blog as the upload target from Images & Files, and MarsEdit will pop the images into a MarsEdit album in your Picasa Web Albums account. Note that Picasa only accepts JPG format images for upload.



Woohoo! I've been wanting this for a long time. And it looks like it works just fine!

Thank you, Daniel Jalkut.

2007/06/04

"REPLACE INTO" for SQL Server

MySQL has handy syntax which lets you look for a record by primary key and, if it exists, update its fields; otherwise insert a new record.

I wish something similar existed for SQL Server. If it does, I can't find it. But there is another way to achieve a similar effect, without too much typing:

BEGIN TRANSACTION;
DELETE FROM my_table WHERE prim_key = @prim_key_val;
INSERT INTO my_table (prim_key, other_field)
VALUES (@prim_key_val, @other_field_val);
COMMIT;

I'm probably missing something; haven't thought this through very carefully.

Cottonwood Rumble


Cottonwood Rumble 1
Originally uploaded by Mitch Chapman
I've been meaning to call a tree trimmer. But I really thought the dead branches were the biggest threat.

2007/06/02

One smart baby

When Bobi brought Aigerim home from Kazakhstan she was not quite nine months old -- way too young to talk.

Aigerim has a stuffed pig of whom she's very fond. Almost from the moment she saw it she's been calling it "n'Goita" or "Nyáh-do" or "Nyáh-da". (We live in New Mexico, so of course we've been repeating this as "Nacho" or "Puerco Nacho".)

But she also uses this word for other things. Typically, she'll repeat it insistently, arms outstretched, while leaning way out from whomever's holding her, as she tries to reach some object.

Lately Bobi has begun to think this might be a word from the Baby House. So this morning we pulled out the Langenscheidt Russian to check. A search in the English section for "want", "give", etc. turned up nothing. But then I flipped over to the Russian section, and there it was:


Надо - need, want


What an awesome little girl.