Run multiple Firefox profiles as separate Applications on Mac

Here is a visual guide to creating multiple Firefox profiles and setting them up to run like separate applications on Snow Leopard.

Creating a new Firefox profile

Open terminal and execute the following command:

/Applications/Firefox.app/Contents/MacOS/firefox-bin --ProfileManager

This should bring up the Firefox Profile Manager –

Firefox_Profile_manager.png

Go ahead and create a brand new profile.

Using Automator to run the new Firefox profile as an application

Now, on to creating a proper Mac application to run Firefox with your chosen profile. Continue reading

Manually resuming a download in Safari

Sometimes you need to manually resume a download in Safari, but you can’t, because the download url was part of a session that has expired.
Mac OS X hints has a handy tip on how to resume a download after Safari crashes – Resuming a download after Safari crashes.

With a slight modification to that process, you can manually resume a download that requires a session, for example by requiring you to log in to a website.

Follow the same steps as in the hint above, and after starting and stopping the download, copy the following two items (substitute the urls from the info.plist in the new download file) to the info.plist in the old download that you want to resume –

<key>NSURLDownloadURL</key>
<string>http://www.mypatchsite.com/patch.sit</string>

<key>DownloadEntryURL</key>
<string>http://www.mypatchsite.com/patch.sit</string>

Now open the old download package in Safari, and it should be able to continue the download from where you left it.

Schema Export in Oracle XE

Oracle XE makes it really easy to export your database schema.

Go to the Oracle XE web interface (running on http://localhost:8080/apex/ by default), and login with your username (not the system user).

Choose Utilities -> Generate DDL. Check the tables for which you want to export the DDL commands, and you are good to go.

Oracle XE export schema

Oracle XE export schema

Google Chrome on Mac

Google Chrome developer release on Mac –

Google Chrome on Mac

Google Chrome on Mac

Being a developer release, it is incomplete.
How incomplete? You can’t run YouTube videos for example, a bunch of other plugins don’t work, and lots of other good stuff missing.
GMail works though, that is what I will be using it for now.

Download it here – Chrome developer release, if you can’t wait to see Chrome running on your Mac.

Google Wave – the successor to GMail

GMail changed the way we use email. It gave us conversations. We started using labels and searches instead of trying to manage folders. It spoilt us by giving us extensions (labs) and themes. It integrated chat and video into the email. And, we started to expect a lot more from web applications.

Google has just unveiled the next big thing they have been working on – Google Wave, and I can safely bet that it is going to have a much bigger impact on how we communicate than GMail did.

I just finished watching the Google Wave Developer Preview at Google I/O 2009.
It is absolutely mind blowing. Not only in how completely it changes the way we think about online conversations, but also in how much the Google team managed to do in the browser. Amaazing!!!

Go watch it now. It is an hour and twenty minutes, but it is time well spent :).

Creating a Viewport in Android

I was writing a simple PacMan like game for Android, and needed to scroll the game area shown as the user moves inside it. In J2ME, you will use LayerManager.setViewWindow to create this kind of Viewport like behaviour. In Android, this can be achieved by using methods in Canvas and View classes.

Here is a simple program demonstrating how to do it –

public class AViewport extends Activity
{

 public void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
 setContentView( new PortView( this ) );

 }

 private class PortView extends View
 {
 // the length and width of a single square
 private int tileSide = 50;
 // the number of squares along x-axis and y-axis
 private int numTiles = 15;

 int fieldWidth = numTiles * tileSide;
 int fieldHeight = numTiles * tileSide;

 private int halfViewWidth;
 private int halfViewHeight;
 private int maxTranslateX;
 private int maxTranslateY;

 int viewWidth = 200;
 int viewHeight = 200;

 private int circleX;
 private int circleY;
 private int diameter = 50;

 private ShapeDrawable one;
 private ShapeDrawable two;

 private ShapeDrawable circle;
 Rect rect = new Rect();
 private Paint p;

 public PortView( Context context )
 {
 super( context );
 one = new ShapeDrawable( new RectShape() );
 two = new ShapeDrawable( new RectShape() );
 circle = new ShapeDrawable( new OvalShape() );
 one.getPaint().setColor( 0x88FF8844 );
 two.getPaint().setColor( 0x8844FF88 );
 circle.getPaint().setColor( 0x99000000 );
 p = new Paint();
 setFocusable( true );
 }

 @Override
 protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
 {
 int width = Math.min( fieldWidth, MeasureSpec.getSize( widthMeasureSpec ) );
 int height = Math.min( fieldHeight, MeasureSpec.getSize( heightMeasureSpec ) );

 viewWidth = width;
 viewHeight = height;
 halfViewWidth = width/2;
 halfViewHeight = height/2;
 maxTranslateX = fieldWidth - width;
 maxTranslateY = fieldHeight - height;

 setMeasuredDimension( width, height );
 }

/*
 _______________________________________
 | ______________                        |
 ||              |                       |
 ||              |vH                     |
 ||              |                       |
 ||______________|                       |
 |       vW                              |fH
 |       .(x1, y1)         ______________|
 |                        |              |
 |                        |              |
 |<---------------------->|              |
 |     maxTranslateX      |______________|
 |_______________________________________|
 fW

 We start translating once x,y goes past x1 (viewWidth/2),y1 (viewHeight/2).
 Movement along x-axis is x - x1, to the maximum of maxTranslateX (fieldWidth - viewWidth).
 The movement along y-axis is calculated similarly.
*/
 @Override
 protected void onDraw( Canvas canvas )
 {
 super.onDraw( canvas );

 canvas.save();

 if ( circleX > halfViewWidth )
 {
 int translateX = Math.min( circleX - halfViewWidth, maxTranslateX );
 canvas.translate( -translateX, 0 );
 }

 if ( circleY > halfViewHeight )
 {
 int translateY = Math.min( circleY - halfViewHeight, maxTranslateY );
 canvas.translate( 0, -translateY );
 }

 drawBoard( canvas );
 drawCircle( canvas );
 canvas.restore();
 }

 private void drawBoard( Canvas canvas )
 {
 int num = 1;
 boolean useTwo = false;
 for ( int row = 0; row < numTiles; row++ )
 {
 int y = row * tileSide;
 for ( int col = 0; col < numTiles; col++ )
 {
 int x = col * tileSide;
 Drawable d = useTwo ? two : one;
 d.setBounds( x, y, x + tileSide, y + tileSide );
 d.draw( canvas );
 canvas.drawText( "" + num, x + 10 , y + 20, p );
 ++num;
 useTwo = !useTwo;
 }
 }
 }

 private void setRect()
 {
 rect.set( circleX, circleY, circleX + diameter, circleY + diameter );
 }

 private void drawCircle( Canvas canvas )
 {
 setRect();
 circle.setBounds( rect );
 circle.draw( canvas );
 }

 @Override
 public boolean onKeyDown( int keyCode, KeyEvent keyEvent )
 {
 boolean handled = true;
 switch ( keyCode )
 {
 case KeyEvent.KEYCODE_DPAD_DOWN:
 if ( circleY <= fieldHeight - diameter - 5 ) circleY += 5;
 break;
 case KeyEvent.KEYCODE_DPAD_UP:
 if( circleY >= 5) circleY -= 5;
 break;
 case KeyEvent.KEYCODE_DPAD_LEFT:
 if( circleX >= 5 ) circleX -= 5;
 break;
 case KeyEvent.KEYCODE_DPAD_RIGHT:
 if( circleX <= fieldWidth - diameter -5 ) circleX += 5;
 break;
 default: handled = false;
 }
 if ( handled )
 {
 invalidate();
 }
 return handled;
 }
 }
}

See the Android API docs of View.onMeasure() and Canvas.translate() methods to understand the code used to create the Viewport.

Setting up WordPress on Ubuntu and Nginx

Finally, after thinking about it many times and never giving it a try, I moved my blog over from wordpress.com to a hosted wordpress installation.

Thanks to kind folks at mensk, the setup was a breeze.
See Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+PHP5+Wordress

If you are following the instructions on that post though, be careful. The first instruction for

sudo ln -s /usr/local/nginx/sites-available/mydomain.com /usr/local/nginx/sites-enabled/mydomain.com

should be

sudo ln -s /usr/local/nginx/sites-available/default /usr/local/nginx/sites-enabled/default

Otherwise, you will get a connection refused error when you try to test just after completing the Nginx setup. Other than that, I was able to get everything up and running with minimal fuss.

This is the first time I am playing with Nginx, that was pretty cool. As soon as I have some time, I should see how well it works with Tomcat.

And, thanks to good people at jestro for writing the Vigilance WordPress theme. It is a minimalistic theme that lets you control many aspects of the blog. If you are going to customize any of the styles in the theme, make sure to read Easy Upgrading With Child Themes.

Code Amnesia context sensitive code search

Code Amnesia looks like a really interesting project.

It allows you to search online for code snippets from within your IDE. The cool thing is that the search is context sensitive. It takes into account the code you are currently editing, which means it can merge the selected snippet into your code.

I don’t think I could use it much in my current work. But, if I was working as a consultant, often working on new projects that used different frameworks, I can see this being a real time and sanity saver.

This is a fairly new project, and only supports Intellij IDEA at the moment. It will be interesting to see what it leads too.

Android on Intellij Idea – run activity on emulator

The official Android plugin is only for Eclipse, but thankfully Android provides Ant support for those of us who prefer other IDEs (http://developer.android.com/guide/developing/other-ide.html).

I use Intellij IDEA, and the main problem for me was that, after building the application using the Ant build script created by activitycreator tool, you have to manually reload the application in the emulator.

This is easily fixed by tweaking the generated Ant build file.
Add the following target to the build.xml –

 <!-- Main activity -->
<property name="main-activity" value="MyMainActivity" />

 <!-- Run the main Activity after reinstall -->
 <target name="run" depends="reinstall">
 <echo>Running ${application-package}.${main-activity} on default emulator...</echo>
 <exec executable="${adb}" failonerror="true">
 <arg value="shell" />
 <arg value="am" />
 <arg value="start" />
 <arg value="-a" />
 <arg value="android.intent.action.MAIN" />
 <arg value="-n" />
 <arg value="${application-package}/${application-package}.${main-activity}" />
 </exec>
 </target>

MyMainActivity is, of course, your main activity. Remember to change the build file if you rename or change the main activity.

I also changed the default target to run, and after loading build.xml as an Ant build file in IDEA, I assigned it a shortcut key.
I also made these changes to ANDROID_SDK/tools/lib/build.template, so from now on, when I create a new Android project, it is already set up this way. If you are editing the template file, use –

 <!-- Main activity -->
<property name="main-activity" value="ACTIVITY_NAME" />

This will automatically pick up the class name you specify on the command line when running activitycreator.